/* The copyright in this software is being made available under the BSD
 * License, included below. This software may be subject to other third party
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
 * Copyright (c) 2002-2016, Audio Video coding Standard Workgroup of China
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *  * Neither the name of Audio Video coding Standard Workgroup of China
 *    nor the names of its contributors maybe
 *    used to endorse or promote products
 *    derived from this software without
 *    specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
#include <linux/platform_device.h>
#include <linux/amlogic/media/utils/amstream.h>
#include <linux/amlogic/media/frame_sync/ptsserv.h>
#include <linux/amlogic/media/canvas/canvas.h>
#include <linux/amlogic/media/vfm/vframe.h>
#include <linux/amlogic/media/vfm/vframe_provider.h>
#include <linux/amlogic/media/vfm/vframe_receiver.h>
#include <linux/amlogic/media/utils/vformat.h>
#include <linux/dma-mapping.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include <linux/slab.h>
/* #include <mach/am_regs.h> */
#include <linux/module.h>
#include <linux/amlogic/media/utils/vdec_reg.h>
#include "../../../stream_input/amports/streambuf_reg.h"
#include "../utils/amvdec.h"
#include <linux/amlogic/media/registers/register.h>
#include "../../../stream_input/amports/amports_priv.h"

#include "avs.h"
#ifdef AVSP_LONG_CABAC

#define DECODING_SANITY_CHECK

#define TRACE 0
#define LIWR_FIX 0
#define pow2(a, b) (1<<b)
#define io_printf pr_info

static unsigned char *local_heap_adr;
static int local_heap_size;
static int local_heap_pos;
static int transcoding_error_flag;

unsigned char *local_alloc(int num, int size)
{
	unsigned char *ret_buf = NULL;
	int alloc_size = num * size;

	if ((local_heap_pos + alloc_size) <= local_heap_size) {
		ret_buf = local_heap_adr + local_heap_pos;
		local_heap_pos += alloc_size;
	} else {
		pr_info(
				"!!!local_alloc(%d) error, local_heap (size %d) is not enough\r\n",
				alloc_size, local_heap_size);
	}
	return ret_buf;
}

int local_heap_init(int size)
{
	/*local_heap_adr = &local_heap[0];*/
	local_heap_adr = (unsigned char *)(avsp_heap_adr +
	MAX_CODED_FRAME_SIZE);
	memset(local_heap_adr, 0, LOCAL_HEAP_SIZE);

	local_heap_size = LOCAL_HEAP_SIZE;
	local_heap_pos = 0;
	return 0;
}

void local_heap_uninit(void)
{
	local_heap_adr = NULL;
	local_heap_size = 0;
	local_heap_pos = 0;
}

#define CODE2D_ESCAPE_SYMBOL 59

const int vlc_golomb_order[3][7][2] =

{{{2, 9}, {2, 9}, {2, 9}, {2, 9}, {2, 9}, {2, 9}, {2, 9}, }, {{3, 9}, {2, 9}, {
		2, 9}, {2, 9}, {2, 9}, {2, 9}, {2, 9}, }, {{2, 9}, {0, 9},
		{1, 9}, {1, 9}, {0, 9}, {-1, -1}, {-1, -1}, }, };

const int MaxRun[3][7] = {{22, 14, 9, 6, 4, 2, 1}, {25, 18, 13, 9, 6, 4, 3}, {
		24, 19, 10, 7, 4, -1, -1} };

const int refabslevel[19][26] = {{4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
		2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1}, {7, 4, 4, 3, 3, 3, 3, 3, 2,
		2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
		10, 6, 4, 4, 3, 3, 3, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1}, {13, 7, 5, 4, 3, 2, 2, -1, -1,
		-1 - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1}, {18, 8, 4, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {22, 7, 3, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1}, {27, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4,
		3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
		2, 2, 2, 2}, {5, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
		2, 2, -1, -1, -1, -1, -1, -1, -1}, {7, 5, 4, 4, 3, 3, 3, 2, 2,
		2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
		{10, 6, 5, 4, 3, 3, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1}, {13, 7, 5, 4,
				3, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1}, {17, 8, 4,
				3, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
				22, 6, 3, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1}, {5, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
				2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1}, {6, 4, 3,
				3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
				2, -1, -1, -1, -1, -1, -1}, {10, 6, 4, 4, 3, 3,
				2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1}, {14, 7, 4, 3, 3, 2,
				2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1}, {20, 7, 3, 2,
				2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1} };

static const int incvlc_intra[7] = {0, 1, 2, 4, 7, 10, 3000};
static const int incvlc_chroma[5] = {0, 1, 2, 4, 3000};

const int AVS_2DVLC_INTRA[7][26][27] = {{{0, 22, 38, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1}, {2, 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4, 44, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1}, {6, 50, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1}, {8, 54, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {10, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1}, {12, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1}, {14, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1}, {16, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {18, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1}, {20, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1}, {24, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1}, {26, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {28, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1}, {30, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1}, {34, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1}, {36, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {40, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1}, {42, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1}, {46, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1}, {48, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {52, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1}, {56, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1}, }, {{8, 0, 4, 15, 27, 41,
		55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1}, {-1, 2, 17, 35, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
		{-1, 6, 25, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
				-1, 9, 33, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1}, {-1, 11, 39, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1}, {-1, 13, 45, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
				-1, 19, 49, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1}, {-1, 21, 51, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1}, {-1, 23, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
				-1, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1}, {-1, 31, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1}, {-1, 37, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
				-1, 43, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1}, {-1, 47, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1}, {-1, 57, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1}, }, {{8, 0, 2, 6,
		13, 17, 27, 35, 45, 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1}, {-1, 4, 11, 21, 33, 49, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1}, {-1, 9, 23, 37, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 15,
		29, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 19, 39, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1}, {-1, 25, 43, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1}, {-1, 31, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 41,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 47, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1}, {-1, 57, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1}, }, {{8, 0, 2, 4, 9, 11, 17, 21, 25, 33, 39, 45, 55, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 6, 13, 19,
		29, 35, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1}, {-1, 15, 27, 41, 57, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1}, {-1, 23, 37, 53, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
		-1, 31, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 43, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1}, {-1, 49, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1}, }, {{6, 0, 2, 4, 7, 9, 11, 15, 17,
		21, 23, 29, 33, 35, 43, 47, 49, 57, -1, -1, -1, -1, -1, -1, -1,
		-1, -1}, {-1, 13, 19, 27, 31, 37, 45, 55, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
		25, 41, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 39, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1}, {-1, 53, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, }, {{0,
		1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 23, 25, 27, 31, 33, 37, 41,
		45, 49, 51, 55, -1, -1, -1, -1, -1}, {-1, 21, 29, 35, 43, 47,
		53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1}, {-1, 39, 57, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1}, }, {{0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19,
		21, 23, 25, 27, 29, 31, 35, 37, 39, 41, 43, 47, 49, 51, 53, 57},
		{-1, 33, 45, 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1} } };

const int AVS_2DVLC_CHROMA[5][26][27] = {{{0, 14, 32, 56, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1}, {2, 48, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1}, {6, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1}, {8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {10,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {12, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1}, {16, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1}, {18, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {20,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {22, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1}, {24, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1}, {26, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {28,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {30, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1}, {34, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1}, {36, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {38,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {40, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1}, {42, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1}, {44, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {46,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {50, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1}, {52, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1}, {54, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, }, {{0, 1, 5, 15, 29,
		43, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1}, {-1, 3, 21, 45, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1}, {-1, 7, 37, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 9, 41, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1}, {-1, 11, 53, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1}, {-1, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
		-1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 19, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1}, {-1, 23, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1}, {-1, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
		-1, 27, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 31, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1}, {-1, 33, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1}, {-1, 35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
		-1, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 47, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1}, {-1, 49, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1}, {-1, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
		-1, 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 57, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, },
		{{2, 0, 3, 7, 11, 17, 27, 33, 47, 53, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
				-1, 5, 13, 21, 37, 55, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1}, {-1, 9, 23, 41, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1}, {-1, 15, 31, 57, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
				19, 43, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1}, {-1, 25, 45, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1}, {-1, 29, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
				35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1}, {-1, 39, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1}, {-1, 49, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
				51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1}, }, {{0, 1, 3, 5, 7, 11, 15, 19, 23, 29,
				35, 43, 47, 53, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1}, {-1, 9, 13, 21, 31, 39, 51,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1}, {-1, 17, 27,
				37, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
				{-1, 25, 41, -1, -1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1}, {
						-1, 33, 55, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1}, {-1, 45, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1}, {
						-1, 49, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1}, {-1, 57, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1}, {
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1}, {-1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1}, {
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1}, {-1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1}, {
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1}, {-1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1}, {
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1}, {-1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1}, {
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1}, {-1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1}, {
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1}, {-1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1}, {
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1}, {-1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1}, {
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1}, {-1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1}, {
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1}, {-1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1, -1,
						-1, -1, -1, -1, -1, -1, -1}, },
		{{0, 1, 3, 5, 7, 9, 11, 13, 15, 19, 21, 23, 27, 29, 33, 37, 41,
				43, 51, 55, -1, -1, -1, -1, -1, -1, -1}, {-1,
				17, 25, 31, 39, 45, 53, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1}, {-1, 35, 49, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1}, {-1, 47, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
				57, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
				-1, -1}, } };

const int UE[64][2] = {{1, 1}, {2, 3}, {3, 3}, {4, 5}, {5, 5}, {6, 5}, {7, 5}, {
		8, 7}, {9, 7}, {10, 7}, {11, 7}, {12, 7}, {13, 7}, {14, 7}, {15,
		7}, {16, 9}, {17, 9}, {18, 9}, {19, 9}, {20, 9}, {21, 9},
		{22, 9}, {23, 9}, {24, 9}, {25, 9}, {26, 9}, {27, 9}, {28, 9}, {
				29, 9}, {30, 9}, {31, 9}, {32, 11}, {33, 11}, {
				34, 11}, {35, 11}, {36, 11}, {37, 11}, {38, 11},
		{39, 11}, {40, 11}, {41, 11}, {42, 11}, {43, 11}, {44, 11}, {45,
				11}, {46, 11}, {47, 11}, {48, 11}, {49, 11}, {
				50, 11}, {51, 11}, {52, 11}, {53, 11}, {54, 11},
		{55, 11}, {56, 11}, {57, 11}, {58, 11}, {59, 11}, {60, 11}, {61,
				11}, {62, 11}, {63, 11}, {64, 13} };

unsigned int src_start;
unsigned int des_start;

#ifdef AVSP_LONG_CABAC

unsigned char *es_buf;
unsigned int es_buf_ptr;
unsigned int es_buf_is_overflow;

#else
FILE *f_es;
#endif
unsigned int es_ptr;
unsigned int es_res;
unsigned int es_res_ptr;
unsigned int previous_es;

void init_es(void)
{

#ifdef AVSP_LONG_CABAC
	es_buf_is_overflow = 0;

	es_buf[0] = 0x00;
	es_buf[1] = 0x00;
	es_buf[2] = 0x01;
	es_buf_ptr = 3;
	es_ptr = 3;
#else
	f_es = fopen("es.out", "wb");
	if (f_es == NULL)
		io_printf(" ERROR : Can not open es.out for write\n");
	putc(0x00, f_es);
	putc(0x00, f_es);
	putc(0x01, f_es);

	es_ptr = 3;
#endif
	es_res = 0;
	es_res_ptr = 0;
	previous_es = 0xff;

}

void push_es(int value, int num)
{
	unsigned char wr_es_data;
	int push_num;
	int push_value;

#ifdef DUMP_DEBUG
	if (avs_get_debug_flag() & ES_DUMP)
		io_printf(" push_es : value : 0x%x, num : %d\n", value, num);
#endif
	while (num > 0) {
		if (num >= 8)
			push_num = 8;
		else
			push_num = num;

		num = num - push_num;
		push_value = (value >> num);

		es_res = (es_res << push_num) | push_value;
		es_res_ptr = es_res_ptr + push_num;

#ifdef DUMP_DEBUG
		if (avs_get_debug_flag() & ES_DUMP)
			io_printf(" #### es_res : 0x%X, es_res_ptr : %d\n",
				es_res, es_res_ptr);
#endif

		while (es_res_ptr >= 8) {
			es_res_ptr = es_res_ptr & 7;
			wr_es_data = (es_res >> es_res_ptr) & 0xff;
			if ((previous_es == 0) & (wr_es_data < 4)) {
				io_printf(
						" Insert 2'b10 for emu at position : %d\n",
						es_ptr);

				es_res_ptr = es_res_ptr + 2;
				wr_es_data = 2;
			}
#ifdef AVSP_LONG_CABAC
#ifdef DUMP_DEBUG
			if (avs_get_debug_flag() & ES_DUMP)
				pr_info("es_buf[%d] = 0x%02x\r\n",
					es_buf_ptr, wr_es_data);
#endif
			if (!es_buf_is_overflow) {
				es_buf[es_buf_ptr++] = wr_es_data;
				if (es_buf_ptr >= MAX_CODED_FRAME_SIZE)
					es_buf_is_overflow = 1;
			}
#else
			putc(wr_es_data, f_es);
#endif
			es_ptr++;
			previous_es = ((previous_es << 8) | wr_es_data)
					& 0xffff;
		}

	}
}

#ifdef BLOCK_SIZE
#undef BLOCK_SIZE
#endif

#define MIN_QP          0
#define MAX_QP          63

#define BLOCK_SIZE      4
#define B8_SIZE         8
#define MB_BLOCK_SIZE   16

#define BLOCK_MULTIPLE      (MB_BLOCK_SIZE/(BLOCK_SIZE*2))

#define DECODE_COPY_MB  0
#define DECODE_MB       1

#define NO_INTRA_PMODE  5
#define INTRA_PMODE_4x4   10
#define NO_INTRA_PMODE_4x4	19
/* 8x8 intra prediction modes */
#define VERT_PRED             0
#define HOR_PRED              1
#define DC_PRED               2
#define DOWN_LEFT_PRED   3
#define DOWN_RIGHT_PRED  4

#define VERT_PRED_4x4   0
#define HOR_PRED_4x4	1
#define DC_PRED_4x4		2
#define DOWN_LEFT_PRED_4x4	3
#define DOWN_RIGHT_PRED_4x4	4

#define HOR_DOWN_PRED_4x4		5
#define VERT_LEFT_PRED_4x4	6
#define HOR_UP_PRED_4x4	   7
#define VERT_RIGHT_PRED_4x4	8

#define DC_PRED_8       0
#define HOR_PRED_8      1
#define VERT_PRED_8     2
#define PLANE_8         3

#define LUMA_16DC       0
#define LUMA_16AC       1
#define LUMA_8x8        2
#define LUMA_8x4        3
#define LUMA_4x8        4
#define LUMA_4x4        5
#define CHROMA_DC       6
#define CHROMA_AC       7
#define NUM_BLOCK_TYPES 8

#define I_PICTURE_START_CODE    0xB3
#define PB_PICTURE_START_CODE   0xB6
#define SLICE_START_CODE_MIN    0x00
#define SLICE_START_CODE_MAX    0xAF
#define USER_DATA_START_CODE    0xB2
#define SEQUENCE_HEADER_CODE    0xB0
#define EXTENSION_START_CODE    0xB5
#define SEQUENCE_END_CODE       0xB1
#define VIDEO_EDIT_CODE         0xB7

#define EOS             1
#define SOP             2
#define SOS             3
#define P8x8    8
#define I8MB    9
#define I4MB   10
#define IBLOCK  11
#define SI4MB   12
#define MAXMODE 13

#define IS_INTRA(MB)    ((MB)->mb_type == I8MB  || (MB)->mb_type == I4MB)
#define IS_NEWINTRA(MB) ((MB)->mb_type == I4MB)
#define IS_OLDINTRA(MB) ((MB)->mb_type == I8MB)
#define IS_INTER(MB)    ((MB)->mb_type != I8MB  && (MB)->mb_type != I4MB)
#define IS_INTERMV(MB)  ((MB)->mb_type != I8MB  && (MB)->mb_type != I4MB\
	&& (MB)->mb_type != 0)

#define IS_DIRECT(MB)   ((MB)->mb_type == 0     && (img->type == B_IMG))
#define IS_COPY(MB)     ((MB)->mb_type == 0     && (img->type == P_IMG))
#define IS_P8x8(MB)     ((MB)->mb_type == P8x8)

#define P_IMG     0
#define B_IMG     1
#define I_IMG     2

#define FIELD     0
#define FRAME     1

#define SE_CABP    21
struct decoding_environment_s {
	unsigned int dbuffer;
	int dbits_to_go;
	unsigned char *dcodestrm;
	int *dcodestrm_len;
};

struct bi_context_type_s {
	unsigned char MPS;
	unsigned int LG_PMPS;
	unsigned char cycno;
};


/**********************************************************************
 * C O N T E X T S   F O R   R M   S Y N T A X   E L E M E N T S
 **********************************************************************
 */

#define NUM_MB_TYPE_CTX  11
#define NUM_B8_TYPE_CTX  9
#define NUM_MV_RES_CTX   10
#define NUM_REF_NO_CTX   6
#define NUM_DELTA_QP_CTX 4
#define NUM_MB_AFF_CTX 4

struct motion_info_contexts_s {
	struct bi_context_type_s mb_type_contexts[4][NUM_MB_TYPE_CTX];
	struct bi_context_type_s b8_type_contexts[2][NUM_B8_TYPE_CTX];
	struct bi_context_type_s mv_res_contexts[2][NUM_MV_RES_CTX];
	struct bi_context_type_s ref_no_contexts[2][NUM_REF_NO_CTX];
	struct bi_context_type_s delta_qp_contexts[NUM_DELTA_QP_CTX];
	struct bi_context_type_s mb_aff_contexts[NUM_MB_AFF_CTX];
#ifdef TEST_WEIGHTING_AEC
struct bi_context_type_s mb_weighting_pred;
#endif
};

#define NUM_IPR_CTX    2
#define NUM_CIPR_CTX   4
#define NUM_CBP_CTX    4
#define NUM_BCBP_CTX   4
#define NUM_MAP_CTX   16
#define NUM_LAST_CTX  16

#define NUM_ONE_CTX    5
#define NUM_ABS_CTX    5

struct texture_info_contexts {
	struct bi_context_type_s ipr_contexts[NUM_IPR_CTX];
	struct bi_context_type_s cipr_contexts[NUM_CIPR_CTX];
	struct bi_context_type_s cbp_contexts[3][NUM_CBP_CTX];
	struct bi_context_type_s bcbp_contexts[NUM_BLOCK_TYPES][NUM_BCBP_CTX];
	struct bi_context_type_s one_contexts[NUM_BLOCK_TYPES][NUM_ONE_CTX];
	struct bi_context_type_s abs_contexts[NUM_BLOCK_TYPES][NUM_ABS_CTX];
	struct bi_context_type_s fld_map_contexts[NUM_BLOCK_TYPES][NUM_MAP_CTX];
	struct bi_context_type_s fld_last_contexts
	[NUM_BLOCK_TYPES][NUM_LAST_CTX];
	struct bi_context_type_s map_contexts[NUM_BLOCK_TYPES][NUM_MAP_CTX];
	struct bi_context_type_s last_contexts[NUM_BLOCK_TYPES][NUM_LAST_CTX];
};
struct img_par;

struct syntaxelement {
	int type;
	int value1;
	int value2;
	int len;
	int inf;
	unsigned int bitpattern;
	int context;
	int k;
	int golomb_grad;
	int golomb_maxlevels;
#if TRACE
#define       TRACESTRING_SIZE 100
	char tracestring[TRACESTRING_SIZE];
#endif

	void (*mapping)(int len, int info, int *value1, int *value2);

	void (*reading)(struct syntaxelement *, struct img_par *,
			struct decoding_environment_s *);

};

struct bitstream_s {

	int read_len;
	int code_len;

	int frame_bitoffset;
	int bitstream_length;

	unsigned char *stream_buffer;
};

struct datapartition {

	struct bitstream_s *bitstream;
	struct decoding_environment_s de_aec;

	int (*read_syntax_element)(struct syntaxelement *, struct img_par *,
			struct datapartition *);
/*!< virtual function;
 * actual method depends on chosen data partition and
 * entropy coding method
 */
};

struct slice_s {
	int picture_id;
	int qp;
	int picture_type;
	int start_mb_nr;
	int max_part_nr;
	int num_mb;

	struct datapartition *part_arr;
	struct motion_info_contexts_s *mot_ctx;
	struct texture_info_contexts *tex_ctx;
	int field_ctx[3][2];
};

struct img_par {
	int number;
	int current_mb_nr;
	int max_mb_nr;
	int current_slice_nr;
	int tr;
	int qp;
	int type;

	int typeb;

	int width;
	int height;
	int width_cr;
	int height_cr;
	int source_bitdepth;
	int mb_y;
	int mb_x;
	int block_y;
	int pix_y;
	int pix_x;
	int pix_c_y;
	int block_x;
	int pix_c_x;

	int ***mv;
	int mpr[16][16];

	int m7[16][16];
	int m8[/*2*/4][8][8];
	int cof[4][/*6*/8][4][4];
	int cofu[4];
	int **ipredmode;
	int quad[256];
	int cod_counter;

	int ***dfmv;
	int ***dbmv;
	int **fw_reffrarr;
	int **bw_reffrarr;

	int ***mv_frm;
	int **fw_reffrarr_frm;
	int **bw_reffrarr_frm;
	int imgtr_next_p;
	int imgtr_last_p;
	int tr_frm;
	int tr_fld;
	int imgtr_last_prev_p;

	int no_forward_reference;
	int seq_header_indicate;
	int b_discard_flag;

	int ***fw_mv;
	int ***bw_mv;
	int subblock_x;
	int subblock_y;

	int buf_cycle;

	int direct_type;

	int ***mv_top;
	int ***mv_bot;
	int **fw_reffrarr_top;
	int **bw_reffrarr_top;
	int **fw_reffrarr_bot;
	int **bw_reffrarr_bot;

	int **ipredmode_top;
	int **ipredmode_bot;
	int ***fw_mv_top;
	int ***fw_mv_bot;
	int ***bw_mv_top;
	int ***bw_mv_bot;
	int ***dfmv_top;
	int ***dbmv_top;
	int ***dfmv_bot;
	int ***dbm_bot;

	int toppoc;
	int bottompoc;
	int framepoc;
	unsigned int frame_num;

	unsigned int pic_distance;
	int delta_pic_order_cnt_bottom;

	signed int pic_distance_msb;
	unsigned int prev_pic_distance_lsb;
	signed int curr_pic_distance_msb;
	unsigned int this_poc;

	int pic_width_inmbs;
	int pic_height_inmbs;
	int pic_size_inmbs;

	int block8_x, block8_y;
	int structure;
	int pn;
	int buf_used;
	int buf_size;
	int picture_structure;
	int advanced_pred_mode_disable;
	int types;
	int current_mb_nr_fld;

	int p_field_enhanced;
	int b_field_enhanced;

	int slice_weighting_flag;
	int lum_scale[4];
	int lum_shift[4];
	int chroma_scale[4];
	int chroma_shift[4];
	int mb_weighting_flag;
	int weighting_prediction;
	int mpr_weight[16][16];
	int top_bot;
	int bframe_number;

	int auto_crop_right;
	int auto_crop_bottom;

	struct slice_s *current_slice;
	int is_v_block;
	int is_intra_block;

	int new_seq_header_flag;
	int new_sequence_flag;
	int last_pic_bbv_delay;

	int sequence_end_flag;
	int is_top_field;

	int abt_flag;
	int qp_shift;

#ifdef EIGHTH
int eighth_subpixel_flag;
int subpixel_precision;
int unit_length;
int subpixel_mask;

int max_mvd;
int min_mvd;
#endif

};

struct macroblock {
	int qp;
	int slice_nr;
	int delta_quant;
	struct macroblock *mb_available[3][3];
	/*!< pointer to neighboring MBs in a 3x3 window of current MB,
	 *which is located at [1][1]
	 * NULL pointer identifies neighboring MBs which are unavailable
	 */

	int mb_type;
	int mvd[2][BLOCK_MULTIPLE][BLOCK_MULTIPLE][2];
	int cbp, cbp_blk, cbp01;
	unsigned long cbp_bits;

	int b8mode[4];
	int b8pdir[4];
	int mb_type_2;
	int c_ipred_mode_2;
	int dct_mode;

	int c_ipred_mode;
	int lf_disable;
	int lf_alpha_c0_offset;
	int lf_beta_offset;

	int CABT[4];
	int CABP[4];
	int cbp_4x4[4];

	int skip_flag;

	struct macroblock *mb_available_up;
	struct macroblock *mb_available_left;
	unsigned int mbaddr_a, mbaddr_b, mbaddr_c, mbaddr_d;
	unsigned int mbavail_a, mbavail_b, mbavail_c, mbavail_d;

};

struct macroblock *mb_data;

struct img_par *img;

struct bitstream_s *curr_stream;

struct datapartition *alloc_partition(int n);

unsigned int vld_mem_start_addr;
unsigned int vld_mem_end_addr;

int marker_bit;

int progressive_sequence;
int horizontal_size;
int vertical_size;

int second_ifield;
int pre_img_type;

/* slice_header() */
int slice_vertical_position;
int slice_vertical_position_extension;
int fixed_picture_qp;
int fixed_slice_qp;
int slice_qp;

/*
 *************************************************************************
 * Function:ue_v, reads an u(v) syntax element, the length in bits is stored in
 the global UsedBits variable
 * Input:
 tracestring
 the string for the trace file
 bitstream
 the stream to be read from
 * Output:
 * Return: the value of the coded syntax element
 * Attention:
 *************************************************************************
 */
/*!
 *  definition of AVS syntaxelements
 *  order of elements follow dependencies for picture reconstruction
 */
/*!
 * \brief   Assignment of old TYPE partition elements to new
 *          elements
 *
 *  old element     | new elements
 *  TYPE_HEADER     | SE_HEADER, SE_PTYPE
 *  TYPE_MBHEADER    | SE_MBTYPE, SE_REFFRAME, SE_INTRAPREDMODE
 *  TYPE_MVD        | SE_MVD
 *  TYPE_CBP        | SE_CBP_INTRA, SE_CBP_INTER * SE_DELTA_QUANT_INTER
 *  SE_DELTA_QUANT_INTRA
 *  TYPE_COEFF_Y    | SE_LUM_DC_INTRA, SE_LUM_AC_INTRA,
    SE_LUM_DC_INTER, SE_LUM_AC_INTER
 *  TYPE_2x2DC      | SE_CHR_DC_INTRA, SE_CHR_DC_INTER
 *  TYPE_COEFF_C    | SE_CHR_AC_INTRA, SE_CHR_AC_INTER
 *  TYPE_EOS        | SE_EOS
 */

#define SE_HEADER           0
#define SE_PTYPE            1
#define SE_MBTYPE           2
#define SE_REFFRAME         3
#define SE_INTRAPREDMODE    4
#define SE_MVD              5
#define SE_CBP_INTRA        6
#define SE_LUM_DC_INTRA     7
#define SE_CHR_DC_INTRA     8
#define SE_LUM_AC_INTRA     9
#define SE_CHR_AC_INTRA     10
#define SE_CBP_INTER        11
#define SE_LUM_DC_INTER     12
#define SE_CHR_DC_INTER     13
#define SE_LUM_AC_INTER     14
#define SE_CHR_AC_INTER     15
#define SE_DELTA_QUANT_INTER      16
#define SE_DELTA_QUANT_INTRA      17
#define SE_BFRAME           18
#define SE_EOS              19
#define SE_MAX_ELEMENTS     20
#define SE_CBP01            21
int chroma_format;
/*
 *************************************************************************
 * Function:Reads bits from the bitstream buffer
 * Input:
 byte buffer[]
 containing VLC-coded data bits
 int totbitoffset
 bit offset from start of partition
 int bytecount
 total bytes in bitstream
 int numbits
 number of bits to read
 * Output:
 * Return:
 * Attention:
 *************************************************************************
 */

int get_bits(unsigned char buffer[], int totbitoffset, int *info, int bytecount,
		int numbits)
{
	register int inf;
	long byteoffset;
	int bitoffset;

	int bitcounter = numbits;

	byteoffset = totbitoffset / 8;
	bitoffset = 7 - (totbitoffset % 8);

	inf = 0;
	while (numbits) {
		inf <<= 1;
		inf |= (buffer[byteoffset] & (0x01 << bitoffset)) >> bitoffset;
		numbits--;
		bitoffset--;
		if (bitoffset < 0) {
			byteoffset++;
			bitoffset += 8;
			if (byteoffset > bytecount)
				return -1;
		}
	}

	*info = inf;


	return bitcounter;
}

/*
 *************************************************************************
 * Function:read FLC codeword from UVLC-partition
 * Input:
 * Output:
 * Return:
 * Attention:
 *************************************************************************
 */

int read_syntaxelement_flc(struct syntaxelement *sym)
{
	int frame_bitoffset = curr_stream->frame_bitoffset;
	unsigned char *buf = curr_stream->stream_buffer;
	int bitstreamlengthinbytes = curr_stream->bitstream_length;

	if ((get_bits(buf, frame_bitoffset, &(sym->inf), bitstreamlengthinbytes,
			sym->len)) < 0)
		return -1;

	curr_stream->frame_bitoffset += sym->len;
	sym->value1 = sym->inf;

#if TRACE
	tracebits2(sym->tracestring, sym->len, sym->inf);
#endif

	return 1;
}

/*
 *************************************************************************
 * Function:ue_v, reads an u(1) syntax element, the length in bits is stored in
 the global UsedBits variable
 * Input:
 tracestring
 the string for the trace file
 bitstream
 the stream to be read from
 * Output:
 * Return: the value of the coded syntax element
 * Attention:
 *************************************************************************
 */
int u_1(char *tracestring)
{
	return u_v(1, tracestring);
}

/*
 *************************************************************************
 * Function:mapping rule for ue(v) syntax elements
 * Input:length and info
 * Output:number in the code table
 * Return:
 * Attention:
 *************************************************************************
 */
void linfo_ue(int len, int info, int *value1, int *dummy)
{
	*value1 = (int)pow2(2, (len / 2)) + info - 1;
}

int u_v(int leninbits, char *tracestring)
{
	struct syntaxelement symbol, *sym = &symbol;

#ifdef AVSP_LONG_CABAC
#else
	assert(curr_stream->stream_buffer != NULL);
#endif
	sym->type = SE_HEADER;
	sym->mapping = linfo_ue;
	sym->len = leninbits;
	read_syntaxelement_flc(sym);

	return sym->inf;
}

/*
 *************************************************************************
 * Function:mapping rule for se(v) syntax elements
 * Input:length and info
 * Output:signed mvd
 * Return:
 * Attention:
 *************************************************************************
 */

void linfo_se(int len, int info, int *value1, int *dummy)
{
	int n;

	n = (int)pow2(2, (len / 2)) + info - 1;
	*value1 = (n + 1) / 2;
	if ((n & 0x01) == 0)
		*value1 = -*value1;

}

/*
 *************************************************************************
 * Function:length and info
 * Input:
 * Output:cbp (intra)
 * Return:
 * Attention:
 *************************************************************************
 */

void linfo_cbp_intra(int len, int info, int *cbp, int *dummy)
{
}

const int NCBP[64][2] = {{4, 0}, {16, 19}, {17, 16}, {19, 15}, {14, 18},
		{9, 11}, {22, 31}, {8, 13}, {11, 17}, {21, 30}, {10, 12},
		{7, 9}, {12, 10}, {6, 7}, {5, 8}, {1, 1}, {35, 4}, {47, 42}, {
				48, 38}, {38, 27}, {46, 39}, {36, 33}, {50, 59},
		{26, 26}, {45, 40}, {52, 58}, {41, 35}, {28, 25}, {37, 29}, {23,
				24}, {31, 28}, {2, 3}, {43, 5}, {51, 51}, {56,
				52}, {39, 37}, {55, 50}, {33, 43}, {62, 63}, {
				27, 44}, {54, 53}, {60, 62}, {40, 48}, {32, 47},
		{42, 34}, {24, 45}, {29, 49}, {3, 6}, {49, 14}, {53, 55}, {57,
				56}, {25, 36}, {58, 54}, {30, 41}, {59, 60}, {
				15, 21}, {61, 57}, {63, 61}, {44, 46}, {18, 22},
		{34, 32}, {13, 20}, {20, 23}, {0, 2} };

unsigned int s1, t1, value_s, value_t;
unsigned char dec_bypass, dec_final;

#define get_byte() {                                         \
	dbuffer = dcodestrm[(*dcodestrm_len)++];\
	dbits_to_go = 7;                        \
}

#define dbuffer         (dep->dbuffer)
#define dbits_to_go     (dep->dbits_to_go)
#define dcodestrm       (dep->dcodestrm)
#define dcodestrm_len   (dep->dcodestrm_len)

#define B_BITS	10

#define LG_PMPS_SHIFTNO 2

#define HALF      (1 << (B_BITS-1))
#define QUARTER   (1 << (B_BITS-2))

unsigned int biari_decode_symbol(struct decoding_environment_s *dep,
		struct bi_context_type_s *bi_ct)
{
	register unsigned char bit;
	register unsigned char s_flag;
	register unsigned char is_lps = 0;
	register unsigned char cwr;
	register unsigned char cycno = bi_ct->cycno;
	register unsigned int lg_pmps = bi_ct->LG_PMPS;
	register unsigned int t_rlps;
	register unsigned int s2, t2;

#ifdef DUMP_DEBUG
	if (avs_get_debug_flag() & AEC_DUMP)
		io_printf("LG_PMPS : %03X, MPS : %d, cycno : %d -- %p\n",
			bi_ct->LG_PMPS, bi_ct->MPS, bi_ct->cycno, bi_ct);
#endif

	bit = bi_ct->MPS;

	cwr = (cycno <= 1) ? 3 : (cycno == 2) ? 4 : 5;

	if (t1 >= (lg_pmps >> LG_PMPS_SHIFTNO)) {
		s2 = s1;
		t2 = t1 - (lg_pmps >> LG_PMPS_SHIFTNO);
		s_flag = 0;
	} else {
		s2 = s1 + 1;
		t2 = 256 + t1 - (lg_pmps >> LG_PMPS_SHIFTNO);
		s_flag = 1;
	}

#ifdef DUMP_DEBUG
	if (avs_get_debug_flag() & AEC_DUMP)
		io_printf(" s2 : %d, t2 : %03X\n", s2, t2);
#endif

	if (s2 > value_s || (s2 == value_s && value_t >= t2)) {
		is_lps = 1;
		bit = !bit;

		t_rlps = (s_flag == 0) ?
				(lg_pmps >> LG_PMPS_SHIFTNO) :
				(t1 + (lg_pmps >> LG_PMPS_SHIFTNO));

		if (s2 == value_s)
			value_t = (value_t - t2);
		else {
			if (--dbits_to_go < 0)
				get_byte();

			value_t = (value_t << 1)
					| ((dbuffer >> dbits_to_go) & 0x01);
			value_t = 256 + value_t - t2;

		}

		while (t_rlps < QUARTER) {
			t_rlps = t_rlps << 1;
			if (--dbits_to_go < 0)
				get_byte();

			value_t = (value_t << 1)
					| ((dbuffer >> dbits_to_go) & 0x01);
		}

		s1 = 0;
		t1 = t_rlps & 0xff;

		value_s = 0;
		while (value_t < QUARTER) {
			int j;

			if (--dbits_to_go < 0)
				get_byte();
			j = (dbuffer >> dbits_to_go) & 0x01;

			value_t = (value_t << 1) | j;
			value_s++;
		}
		value_t = value_t & 0xff;
	} else {

		s1 = s2;
		t1 = t2;
	}

	if (dec_bypass)
		return bit;

	if (is_lps)
		cycno = (cycno <= 2) ? (cycno + 1) : 3;
	else if (cycno == 0)
		cycno = 1;
	bi_ct->cycno = cycno;

	if (is_lps) {
		switch (cwr) {
		case 3:
			lg_pmps = lg_pmps + 197;
			break;
		case 4:
			lg_pmps = lg_pmps + 95;
			break;
		default:
			lg_pmps = lg_pmps + 46;
		}

		if (lg_pmps >= (256 << LG_PMPS_SHIFTNO)) {
			lg_pmps = (512 << LG_PMPS_SHIFTNO) - 1 - lg_pmps;
			bi_ct->MPS = !(bi_ct->MPS);
		}
	} else {
#ifdef DUMP_DEBUG
		if (avs_get_debug_flag() & AEC_DUMP)
			io_printf(" - lg_pmps_MPS : %X (%X - %X - %X)\n",
					lg_pmps - (unsigned int)(lg_pmps>>cwr)
					- (unsigned int)(lg_pmps>>(cwr+2)),
					lg_pmps,
					(unsigned int)(lg_pmps>>cwr),
					(unsigned int)(lg_pmps>>(cwr+2))
			);
#endif
		lg_pmps = lg_pmps - (unsigned int)(lg_pmps >> cwr)
				- (unsigned int)(lg_pmps >> (cwr + 2));
	}

	bi_ct->LG_PMPS = lg_pmps;

	return bit;
}

unsigned int biari_decode_symbolw(struct decoding_environment_s *dep,
		struct bi_context_type_s *bi_ct1,
		struct bi_context_type_s *bi_ct2)
{
	register unsigned char bit1, bit2;
	register unsigned char pred_mps, bit;
	register unsigned int lg_pmps;
	register unsigned char cwr1, cycno1 = bi_ct1->cycno;
	register unsigned char cwr2, cycno2 = bi_ct2->cycno;
	register unsigned int lg_pmps1 = bi_ct1->LG_PMPS;
	register unsigned int lg_pmps2 =
			bi_ct2->LG_PMPS;
	register unsigned int t_rlps;
	register unsigned char s_flag, is_lps = 0;
	register unsigned int s2, t2;


	bit1 = bi_ct1->MPS;
	bit2 = bi_ct2->MPS;

	cwr1 = (cycno1 <= 1) ? 3 : (cycno1 == 2) ? 4 : 5;
	cwr2 = (cycno2 <= 1) ? 3 : (cycno2 == 2) ? 4 : 5;

	if (bit1 == bit2) {
		pred_mps = bit1;
		lg_pmps = (lg_pmps1 + lg_pmps2) / 2;
	} else {
		if (lg_pmps1 < lg_pmps2) {
			pred_mps = bit1;
			lg_pmps = (256 << LG_PMPS_SHIFTNO) - 1
					- ((lg_pmps2 - lg_pmps1) >> 1);
		} else {
			pred_mps = bit2;
			lg_pmps = (256 << LG_PMPS_SHIFTNO) - 1
					- ((lg_pmps1 - lg_pmps2) >> 1);
		}
	}

#ifdef DUMP_DEBUG
	if (avs_get_debug_flag() & AEC_DUMP)
		io_printf(" - Begin - LG_PMPS : %03X, MPS : %d\n",
			lg_pmps, pred_mps);
#endif
	if (t1 >= (lg_pmps >> LG_PMPS_SHIFTNO)) {
		s2 = s1;
		t2 = t1 - (lg_pmps >> LG_PMPS_SHIFTNO);
		s_flag = 0;
	} else {
		s2 = s1 + 1;
		t2 = 256 + t1 - (lg_pmps >> LG_PMPS_SHIFTNO);
		s_flag = 1;
	}

	bit = pred_mps;
	if (s2 > value_s || (s2 == value_s && value_t >= t2)) {
		is_lps = 1;
		bit = !bit;
		t_rlps = (s_flag == 0) ?
				(lg_pmps >> LG_PMPS_SHIFTNO) :
				(t1 + (lg_pmps >> LG_PMPS_SHIFTNO));

		if (s2 == value_s)
			value_t = (value_t - t2);
		else {
			if (--dbits_to_go < 0)
				get_byte();

			value_t = (value_t << 1)
					| ((dbuffer >> dbits_to_go) & 0x01);
			value_t = 256 + value_t - t2;
		}

		while (t_rlps < QUARTER) {
			t_rlps = t_rlps << 1;
			if (--dbits_to_go < 0)
				get_byte();

			value_t = (value_t << 1)
					| ((dbuffer >> dbits_to_go) & 0x01);
		}
		s1 = 0;
		t1 = t_rlps & 0xff;

		value_s = 0;
		while (value_t < QUARTER) {
			int j;

			if (--dbits_to_go < 0)
				get_byte();
			j = (dbuffer >> dbits_to_go) & 0x01;

			value_t = (value_t << 1) | j;
			value_s++;
		}
		value_t = value_t & 0xff;
	} else {
		s1 = s2;
		t1 = t2;
	}

	if (bit != bit1) {
		cycno1 = (cycno1 <= 2) ? (cycno1 + 1) : 3;
	} else {
		if (cycno1 == 0)
			cycno1 = 1;
	}

	if (bit != bit2) {
		cycno2 = (cycno2 <= 2) ? (cycno2 + 1) : 3;
	} else {
		if (cycno2 == 0)
			cycno2 = 1;
	}
	bi_ct1->cycno = cycno1;
	bi_ct2->cycno = cycno2;

	{

		if (bit == bit1) {
			lg_pmps1 =
					lg_pmps1
				- (unsigned int)(lg_pmps1
					>> cwr1)
				- (unsigned int)(lg_pmps1
					>> (cwr1
					+ 2));
		} else {
			switch (cwr1) {
			case 3:
				lg_pmps1 = lg_pmps1 + 197;
				break;
			case 4:
				lg_pmps1 = lg_pmps1 + 95;
				break;
			default:
				lg_pmps1 = lg_pmps1 + 46;
			}

			if (lg_pmps1 >= (256 << LG_PMPS_SHIFTNO)) {
				lg_pmps1 = (512 << LG_PMPS_SHIFTNO) - 1
						- lg_pmps1;
				bi_ct1->MPS = !(bi_ct1->MPS);
			}
		}
		bi_ct1->LG_PMPS = lg_pmps1;

		if (bit == bit2) {
			lg_pmps2 =
					lg_pmps2
				- (unsigned int)(lg_pmps2
				>> cwr2)
				- (unsigned int)(lg_pmps2
				>> (cwr2
				+ 2));
		} else {
			switch (cwr2) {
			case 3:
				lg_pmps2 = lg_pmps2 + 197;
				break;
			case 4:
				lg_pmps2 = lg_pmps2 + 95;
				break;
			default:
				lg_pmps2 = lg_pmps2 + 46;
			}

			if (lg_pmps2 >= (256 << LG_PMPS_SHIFTNO)) {
				lg_pmps2 = (512 << LG_PMPS_SHIFTNO) - 1
						- lg_pmps2;
				bi_ct2->MPS = !(bi_ct2->MPS);
			}
		}
		bi_ct2->LG_PMPS = lg_pmps2;
	}


	return bit;
}

/*!
 ************************************************************************
 * \brief
 *    biari_decode_symbol_eq_prob():
 * \return
 *    the decoded symbol
 ************************************************************************
 */
unsigned int biari_decode_symbol_eq_prob(struct decoding_environment_s *dep)
{
	unsigned char bit;
	struct bi_context_type_s octx;
	struct bi_context_type_s *ctx = &octx;

	ctx->LG_PMPS = (QUARTER << LG_PMPS_SHIFTNO) - 1;
	ctx->MPS = 0;
	ctx->cycno = 0xfe;
	dec_bypass = 1;
	bit = biari_decode_symbol(dep, ctx);
	dec_bypass = 0;
	return bit;
}

unsigned int biari_decode_final(struct decoding_environment_s *dep)
{
	unsigned char bit;
	struct bi_context_type_s octx;
	struct bi_context_type_s *ctx = &octx;

	ctx->LG_PMPS = 1 << LG_PMPS_SHIFTNO;
	ctx->MPS = 0;
	ctx->cycno = 0xff;
	dec_final = 1;
	bit = biari_decode_symbol(dep, ctx);
	dec_final = 0;
	return bit;
}

int i_8(char *tracestring)
{
	int frame_bitoffset = curr_stream->frame_bitoffset;
	unsigned char *buf = curr_stream->stream_buffer;
	int bitstreamlengthinbytes = curr_stream->bitstream_length;
	struct syntaxelement symbol, *sym = &symbol;
#ifdef AVSP_LONG_CABAC
#else
	assert(curr_stream->stream_buffer != NULL);
#endif

	sym->len = 8;
	sym->type = SE_HEADER;
	sym->mapping = linfo_ue;

	if ((get_bits(buf, frame_bitoffset, &(sym->inf), bitstreamlengthinbytes,
			sym->len)) < 0)
		return -1;
	curr_stream->frame_bitoffset += sym->len;
	sym->value1 = sym->inf;
	if (sym->inf & 0x80)
		sym->inf = -(~((int)0xffffff00 | sym->inf) + 1);
#if TRACE
	tracebits2(sym->tracestring, sym->len, sym->inf);
#endif
	return sym->inf;
}

/*!
 ************************************************************************
 * \brief
 *    arideco_bits_read
 ************************************************************************
 */
int arideco_bits_read(struct decoding_environment_s *dep)
{

	return 8 * ((*dcodestrm_len) - 1) + (8 - dbits_to_go);
}

/*!
 ************************************************************************
 * \brief
 *    arithmetic decoding
 ************************************************************************
 */
int read_syntaxelement_aec(struct syntaxelement *se, struct img_par *img,
		struct datapartition *this_data_part)
{
	int curr_len;
	struct decoding_environment_s *dep_dp = &(this_data_part->de_aec);

	curr_len = arideco_bits_read(dep_dp);

	se->reading(se, img, dep_dp);

	se->len = (arideco_bits_read(dep_dp) - curr_len);
	return se->len;
}

/*!
 ************************************************************************
 * \brief
 *    This function is used to arithmetically decode the
 *    run length info of the skip mb
 ************************************************************************
 */
void readrunlenghtfrombuffer_aec(struct syntaxelement *se, struct img_par *img,
		struct decoding_environment_s *dep_dp)
{
	struct bi_context_type_s *pctx;
	int ctx, symbol;

	pctx = img->current_slice->tex_ctx->one_contexts[0];
	symbol = 0;
	ctx = 0;
	while (biari_decode_symbol(dep_dp, pctx + ctx) == 0) {
		symbol += 1;
		ctx++;
		if (ctx >= 3)
			ctx = 3;
	}
	se->value1 = symbol;
#if TRACE
	fprintf(p_trace, "@%d%s\t\t\t%d\n",
		symbol_count++, se->tracestring, se->value1);
	fflush(p_trace);
#endif
}

/*!
 ************************************************************************
 * \brief
 *    This function is used to arithmetically decode a pair of
 *    intra prediction modes of a given MB.
 ************************************************************************
 */
int mapd_intrap[5] = {0, 2, 3, 4, 1};
void read_intrapredmode_aec(struct syntaxelement *se, struct img_par *img,
		struct decoding_environment_s *dep_dp)
{
	struct bi_context_type_s *pctx;
	int ctx, symbol;

	pctx = img->current_slice->tex_ctx->one_contexts[1];
	symbol = 0;
	ctx = 0;
#ifdef DUMP_DEBUG
	if (avs_get_debug_flag() & AEC_DUMP)
		io_printf(" -- read_intrapredmode_aec ctx : %d\n", ctx);
#endif
	while (biari_decode_symbol(dep_dp, pctx + ctx) == 0) {
		symbol += 1;
		ctx++;
		if (ctx >= 3)
			ctx = 3;
#ifdef DUMP_DEBUG
		if (avs_get_debug_flag() & AEC_DUMP)
			io_printf(" -- read_intrapredmode_aec ctx : %d\n", ctx);
#endif
		if (symbol == 4)
			break;
		}
	se->value1 = mapd_intrap[symbol] - 1;

#if TRACE
	fprintf(p_trace, "@%d %s\t\t\t%d\n",
		symbol_count++, se->tracestring, se->value1);
	fflush(p_trace);
#endif
}

/*!
 ************************************************************************
 * \brief
 *    decoding of unary binarization using one or 2 distinct
 *    models for the first and all remaining bins; no terminating
 *    "0" for max_symbol
 ***********************************************************************
 */
unsigned int unary_bin_max_decode(struct decoding_environment_s *dep_dp,
		struct bi_context_type_s *ctx,
		int ctx_offset, unsigned int max_symbol)
{
	unsigned int l;
	unsigned int symbol;
	struct bi_context_type_s *ictx;

	symbol = biari_decode_symbol(dep_dp, ctx);

	if (symbol == 0)
		return 0;

	if (max_symbol == 1)
		return symbol;
	symbol = 0;
	ictx = ctx + ctx_offset;
	do {
		l = biari_decode_symbol(dep_dp, ictx);
		symbol++;
	} while ((l != 0) && (symbol < max_symbol - 1));
	if ((l != 0) && (symbol == max_symbol - 1))
		symbol++;
	return symbol;
}

/*!
 ************************************************************************
 * \brief
 *    decoding of unary binarization using one or 2 distinct
 *    models for the first and all remaining bins
 ***********************************************************************
 */
unsigned int unary_bin_decode(struct decoding_environment_s *dep_dp,
		struct bi_context_type_s *ctx, int ctx_offset)
{
	unsigned int l;
	unsigned int symbol;
	struct bi_context_type_s *ictx;

	symbol = 1 - biari_decode_symbol(dep_dp, ctx);

	if (symbol == 0)
		return 0;
	symbol = 0;
	ictx = ctx + ctx_offset;
	do {
		l = 1 - biari_decode_symbol(dep_dp, ictx);
		symbol++;
	} while (l != 0);
	return symbol;
}

/*!
 ************************************************************************
 * \brief
 *    This function is used to arithmetically decode the chroma
 *    intra prediction mode of a given MB.
 ************************************************************************
 */
void read_cipredmode_aec(struct syntaxelement *se,
	struct img_par *img,
		struct decoding_environment_s *dep_dp)
{
	struct texture_info_contexts *ctx = img->current_slice->tex_ctx;
	struct macroblock *curr_mb = &mb_data[img->current_mb_nr];
	int act_ctx, a, b;
	int act_sym = se->value1;

	if (curr_mb->mb_available_up == NULL)
		b = 0;
	else {
		/*if ( (curr_mb->mb_available_up)->mb_type==IPCM)
		 * b=0;
		 * else
		 */
		b = (((curr_mb->mb_available_up)->c_ipred_mode != 0) ? 1 : 0);
	}

	if (curr_mb->mb_available_left == NULL)
		a = 0;
	else {
		/* if ( (curr_mb->mb_available_left)->mb_type==IPCM)
		 * a=0;
		 * else
		 */
		a = (((curr_mb->mb_available_left)->c_ipred_mode != 0) ? 1 : 0);
	}

	act_ctx = a + b;


	act_sym = biari_decode_symbol(dep_dp, ctx->cipr_contexts + act_ctx);

	if (act_sym != 0)
		act_sym = unary_bin_max_decode(dep_dp, ctx->cipr_contexts + 3,
				0, 2) + 1;

	se->value1 = act_sym;

#if TRACE
	fprintf(p_trace, "@%d %s\t\t%d\n",
		symbol_count++, se->tracestring, se->value1);
	fflush(p_trace);
#endif

}

int slice_header(char *buf, int startcodepos, int length)
{
	int i;

	int weight_para_num = 0;
	int mb_row;
	int mb_column;
	int mb_index;
	int mb_width, mb_height;

	mb_column = 0;

	memcpy(curr_stream->stream_buffer, buf, length);
	curr_stream->code_len = curr_stream->bitstream_length = length;

	curr_stream->read_len =
	curr_stream->frame_bitoffset = (startcodepos) * 8;
	slice_vertical_position = u_v(8, "slice vertical position");

	push_es(slice_vertical_position, 8);

#ifdef DUMP_DEBUG
	if (avs_get_debug_flag() & SLICE_INFO_DUMP)
		io_printf(" * 8-bits slice_vertical_position : %d\n",
			slice_vertical_position);
#endif

	if (vertical_size > 2800) {
		slice_vertical_position_extension = u_v(3,
				"slice vertical position extension");
		push_es(slice_vertical_position_extension, 3);

	}

	if (vertical_size > 2800)
		mb_row = (slice_vertical_position_extension << 7)
				+ slice_vertical_position;
	else
		mb_row = slice_vertical_position;

	mb_width = (horizontal_size + 15) / 16;
	if (!progressive_sequence)
		mb_height = 2 * ((vertical_size + 31) / 32);
	else
		mb_height = (vertical_size + 15) / 16;


	mb_index = mb_row * mb_width + mb_column;

	if (!img->picture_structure && img->type == I_IMG
			&& (mb_index >= mb_width * mb_height / 2)) {
		second_ifield = 1;
		img->type = P_IMG;
		pre_img_type = P_IMG;
	}

	{
		if (!fixed_picture_qp) {
			fixed_slice_qp = u_v(1, "fixed_slice_qp");
			push_es(fixed_slice_qp, 1);
#ifdef DUMP_DEBUG
			if (avs_get_debug_flag() & SLICE_INFO_DUMP)
				io_printf(" * 1-bit fixed_slice_qp : %d\n",
					fixed_slice_qp);
#endif
			slice_qp = u_v(6, "slice_qp");
			push_es(slice_qp, 6);
#ifdef DUMP_DEBUG
			if (avs_get_debug_flag() & SLICE_INFO_DUMP)
				io_printf(" * 6-bits slice_qp : %d\n",
					slice_qp);
#endif

			img->qp = slice_qp;
		}

		if (img->type != I_IMG) {
			img->slice_weighting_flag = u_v(1,
					"slice weighting flag");

			if (img->slice_weighting_flag) {

				if (second_ifield && !img->picture_structure)
					weight_para_num = 1;
				else if (img->type == P_IMG
						&& img->picture_structure)
					weight_para_num = 2;
				else if (img->type == P_IMG
						&& !img->picture_structure)
					weight_para_num = 4;
				else if (img->type == B_IMG
						&& img->picture_structure)
					weight_para_num = 2;
				else if (img->type == B_IMG
						&& !img->picture_structure)
					weight_para_num = 4;

#ifdef DUMP_DEBUG
				if (avs_get_debug_flag() & SLICE_INFO_DUMP)
					io_printf(" - weight_para_num : %d\n",
						weight_para_num);
#endif
				for (i = 0; i < weight_para_num; i++) {
					img->lum_scale[i] = u_v(8,
							"luma scale");

					img->lum_shift[i] = i_8("luma shift");

					marker_bit = u_1("insert bit");


					{
						img->chroma_scale[i] = u_v(8,
								"chroma scale");

						img->chroma_shift[i] = i_8(
								"chroma shift");

						marker_bit = u_1("insert bit");

					}
				}
				img->mb_weighting_flag = u_v(1,
						"MB weighting flag");

			}
		}
	}


#if 1
	return mb_index;
#endif
}

void no_mem_exit(char *where)
{
	io_printf("%s\r\n", where);
}

unsigned char bit[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};

struct inputstream_s {
	/*FILE *f;*/
	unsigned char buf[SVA_STREAM_BUF_SIZE];
	unsigned int uclear_bits;
	unsigned int upre_3bytes;
	int ibyte_position;
	int ibuf_bytesnum;
	int iclear_bitsnum;
	int istuff_bitsnum;
	int ibits_count;
};

struct inputstream_s IRABS;
struct inputstream_s *p_irabs = &IRABS;

struct stat_bits {
	int curr_frame_bits;
	int prev_frame_bits;
	int emulate_bits;
	int prev_emulate_bits;
	int last_unit_bits;
	int bitrate;
	int total_bitrate[1000];
	int coded_pic_num;
	int time_s;
};

struct stat_bits *stat_bits_ptr;

unsigned char *temp_slice_buf;
int start_codeposition;
int first_slice_length;
int first_slice_startpos;

int bitstream_buf_used;
int startcode_offset;

int bitstream_read_ptr;

int demulate_enable;

int last_dquant;

int total_mb_count;

int current_mb_skip;

int skip_mode_flag;

int current_mb_intra;

/*
 *************************************************************************
 * Function: Check start code's type
 * Input:
 * Output:
 * Return:
 * Author: XZHENG, 20080515
 *************************************************************************
 */
void check_type(int startcode)
{
	startcode = startcode & 0x000000ff;
	switch (startcode) {
	case 0xb0:
	case 0xb2:
	case 0xb5:
		demulate_enable = 0;
		break;
	default:
		demulate_enable = 1;
		break;
	}

}
/*
 *************************************************************************
 * Function:
 * Input:
 * Output:
 * Return:  0 : OK
 -1 : arrive at stream end
 -2 : meet another start code
 * Attention:
 *************************************************************************
 */
int clear_nextbyte(struct inputstream_s *p)
{
	int i, k, j;
	unsigned char temp[3];

	i = p->ibyte_position;
	k = p->ibuf_bytesnum - i;
	if (k < 3) {
		for (j = 0; j < k; j++)
			temp[j] = p->buf[i + j];

		p->ibuf_bytesnum = read_bitstream(p->buf + k,
				SVA_STREAM_BUF_SIZE - k);
		bitstream_buf_used++;
		if (p->ibuf_bytesnum == 0) {
			if (k > 0) {
				while (k > 0) {
					p->upre_3bytes = ((p->upre_3bytes << 8)
							| p->buf[i])
							& 0x00ffffff;
					if (p->upre_3bytes < 4
							&& demulate_enable) {
						p->uclear_bits =
						(p->uclear_bits
						<< 6)
						| (p->buf[i]
						>> 2);
						p->iclear_bitsnum += 6;
						stat_bits_ptr->emulate_bits
						+= 2;
					} else {
						p->uclear_bits = (p->uclear_bits
						<< 8)
						| p->buf[i];
						p->iclear_bitsnum += 8;
					}
					p->ibyte_position++;
					k--;
					i++;
				}
				return 0;
			} else {
				return -1;
			}
		} else {
			for (j = 0; j < k; j++)
				p->buf[j] = temp[j];
			p->ibuf_bytesnum += k;
			i = p->ibyte_position = 0;
		}
	}
	if (p->buf[i] == 0 && p->buf[i + 1] == 0 && p->buf[i + 2] == 1)
		return -2;
	p->upre_3bytes = ((p->upre_3bytes << 8) | p->buf[i]) & 0x00ffffff;
	if (p->upre_3bytes < 4 && demulate_enable) {
		p->uclear_bits = (p->uclear_bits << 6) | (p->buf[i] >> 2);
		p->iclear_bitsnum += 6;
		stat_bits_ptr->emulate_bits += 2;
	} else {
		p->uclear_bits = (p->uclear_bits << 8) | p->buf[i];
		p->iclear_bitsnum += 8;
	}
	p->ibyte_position++;
	return 0;
}

/*
 *************************************************************************
 * Function:
 * Input:
 * Output:
 * Return:  0 : OK
 -1 : arrive at stream end
 -2 : meet another start code
 * Attention:
 *************************************************************************
 */
int read_n_bit(struct inputstream_s *p, int n, int *v)
{
	int r;
	unsigned int t;

	while (n > p->iclear_bitsnum) {
		r = clear_nextbyte(p);
		if (r) {
			if (r == -1) {
				if (p->ibuf_bytesnum - p->ibyte_position > 0)
					break;
			}
			return r;
		}
	}
	t = p->uclear_bits;
	r = 32 - p->iclear_bitsnum;
	*v = (t << r) >> (32 - n);
	p->iclear_bitsnum -= n;
	return 0;
}

#ifdef AVSP_LONG_CABAC
unsigned char TMP_BUF[2 * SVA_STREAM_BUF_SIZE];
int tmp_buf_wr_ptr;
int tmp_buf_rd_ptr;
int tmp_buf_count;
#endif
void open_irabs(struct inputstream_s *p)
{
	p->uclear_bits = 0xffffffff;
	p->ibyte_position = 0;
	p->ibuf_bytesnum = 0;
	p->iclear_bitsnum = 0;
	p->istuff_bitsnum = 0;
	p->ibits_count = 0;
	p->upre_3bytes = 0;

	bitstream_buf_used = 0;
	bitstream_read_ptr = (src_start - 16) & 0xfffffff0;

#ifdef AVSP_LONG_CABAC
	tmp_buf_count = 0;
	tmp_buf_wr_ptr = 0;
	tmp_buf_rd_ptr = 0;
#endif

}

void move_bitstream(unsigned int move_from_addr, unsigned int move_to_addr,
		int move_size)
{
	int move_bytes_left = move_size;
	unsigned int move_read_addr;
	unsigned int move_write_addr = move_to_addr;

	int move_byte;
	unsigned int data32;

	while (move_from_addr > vld_mem_end_addr) {
		move_from_addr = move_from_addr + vld_mem_start_addr
				- vld_mem_end_addr - 8;
	}
	move_read_addr = move_from_addr;
	while (move_bytes_left > 0) {
		move_byte = move_bytes_left;
		if (move_byte > 512)
			move_byte = 512;
		if ((move_read_addr + move_byte) > vld_mem_end_addr)
			move_byte = (vld_mem_end_addr + 8) - move_read_addr;

		WRITE_VREG(LMEM_DMA_ADR, move_read_addr);
		WRITE_VREG(LMEM_DMA_COUNT, move_byte / 2);
		WRITE_VREG(LMEM_DMA_CTRL, 0xc200);

		data32 = 0x8000;
		while (data32 & 0x8000)
			data32 = READ_VREG(LMEM_DMA_CTRL);

		WRITE_VREG(LMEM_DMA_ADR, move_write_addr);
		WRITE_VREG(LMEM_DMA_COUNT, move_byte / 2);
		WRITE_VREG(LMEM_DMA_CTRL, 0x8200);

		data32 = 0x8000;
		while (data32 & 0x8000)
			data32 = READ_VREG(LMEM_DMA_CTRL);

		data32 = 0x0fff;
		while (data32 & 0x0fff)
			data32 = READ_VREG(WRRSP_LMEM);

#ifdef DUMP_DEBUG
		if (avs_get_debug_flag() & STREAM_INFO_DUMP)
			io_printf("  2 MOVE %d Bytes from 0x%x to 0x%x\n",
				move_byte, move_read_addr, move_write_addr);
#endif

		move_read_addr = move_read_addr + move_byte;
		if (move_read_addr > vld_mem_end_addr)
			move_read_addr = vld_mem_start_addr;
		move_write_addr = move_write_addr + move_byte;
		move_bytes_left = move_bytes_left - move_byte;
	}

}

int read_bitstream(unsigned char *buf, int size)
{
	int i;

#ifdef AVSP_LONG_CABAC

	unsigned int *TMP_BUF_32 = (unsigned int *)bitstream_read_tmp;

	if (tmp_buf_count < size) {
		dma_sync_single_for_cpu(amports_get_dma_device(),
				bitstream_read_tmp_phy, SVA_STREAM_BUF_SIZE,
				DMA_FROM_DEVICE);

		move_bitstream(bitstream_read_ptr, bitstream_read_tmp_phy,
				SVA_STREAM_BUF_SIZE);

		for (i = 0; i < SVA_STREAM_BUF_SIZE / 8; i++) {
			TMP_BUF[tmp_buf_wr_ptr++] =
					(TMP_BUF_32[2 * i + 1] >> 24) & 0xff;
			if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
				tmp_buf_wr_ptr = 0;
			TMP_BUF[tmp_buf_wr_ptr++] =
					(TMP_BUF_32[2 * i + 1] >> 16) & 0xff;
			if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
				tmp_buf_wr_ptr = 0;
			TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 1] >> 8)
					& 0xff;
			if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
				tmp_buf_wr_ptr = 0;
			TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 1] >> 0)
					& 0xff;
			if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
				tmp_buf_wr_ptr = 0;
			TMP_BUF[tmp_buf_wr_ptr++] =
					(TMP_BUF_32[2 * i + 0] >> 24) & 0xff;
			if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
				tmp_buf_wr_ptr = 0;
			TMP_BUF[tmp_buf_wr_ptr++] =
					(TMP_BUF_32[2 * i + 0] >> 16) & 0xff;
			if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
				tmp_buf_wr_ptr = 0;
			TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 0] >> 8)
					& 0xff;
			if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
				tmp_buf_wr_ptr = 0;
			TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 0] >> 0)
					& 0xff;
			if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
				tmp_buf_wr_ptr = 0;
		}
		tmp_buf_count = tmp_buf_count + SVA_STREAM_BUF_SIZE;
		bitstream_read_ptr = bitstream_read_ptr + SVA_STREAM_BUF_SIZE;
	}

#ifdef DUMP_DEBUG
	if (avs_get_debug_flag() & STREAM_INFO_DUMP)
		io_printf(" Read %d bytes from %d, size left : %d\n",
			size, tmp_buf_rd_ptr, tmp_buf_count);
#endif
	for (i = 0; i < size; i++) {
		buf[i] = TMP_BUF[tmp_buf_rd_ptr++];
		if (tmp_buf_rd_ptr >= (2 * SVA_STREAM_BUF_SIZE))
			tmp_buf_rd_ptr = 0;
	}
	tmp_buf_count = tmp_buf_count - size;

#else
	for (i = 0; i < size; i++)
		buf[i] = tmp_stream[bitstream_read_ptr + i];
	bitstream_read_ptr = bitstream_read_ptr + size;
#endif

	return size;
}

int next_startcode(struct inputstream_s *p)
{
	int i, m;
	unsigned char a = 0, b = 0;

	m = 0;

	while (1) {
		if (p->ibyte_position >= p->ibuf_bytesnum - 2) {
			m = p->ibuf_bytesnum - p->ibyte_position;
			if (m < 0)
				return -2;
			if (m == 1)
				b = p->buf[p->ibyte_position + 1];
			if (m == 2) {
				b = p->buf[p->ibyte_position + 1];
				a = p->buf[p->ibyte_position];
			}
			p->ibuf_bytesnum = read_bitstream(p->buf,
					SVA_STREAM_BUF_SIZE);
			p->ibyte_position = 0;
			bitstream_buf_used++;
		}

		if (p->ibuf_bytesnum + m < 3)
			return -1;

		if (m == 1 && b == 0 && p->buf[0] == 0 && p->buf[1] == 1) {
			p->ibyte_position = 2;
			p->iclear_bitsnum = 0;
			p->istuff_bitsnum = 0;
			p->ibits_count += 24;
			p->upre_3bytes = 1;
			return 0;
		}

		if (m == 2 && b == 0 && a == 0 && p->buf[0] == 1) {
			p->ibyte_position = 1;
			p->iclear_bitsnum = 0;
			p->istuff_bitsnum = 0;
			p->ibits_count += 24;
			p->upre_3bytes = 1;
			return 0;
		}

		if (m == 2 && b == 0 && p->buf[0] == 0 && p->buf[1] == 1) {
			p->ibyte_position = 2;
			p->iclear_bitsnum = 0;
			p->istuff_bitsnum = 0;
			p->ibits_count += 24;
			p->upre_3bytes = 1;
			return 0;
		}

		for (i = p->ibyte_position; i < p->ibuf_bytesnum - 2; i++) {
			if (p->buf[i] == 0 && p->buf[i + 1] == 0
					&& p->buf[i + 2] == 1) {
				p->ibyte_position = i + 3;
				p->iclear_bitsnum = 0;
				p->istuff_bitsnum = 0;
				p->ibits_count += 24;
				p->upre_3bytes = 1;
				return 0;
			}
			p->ibits_count += 8;
		}
		p->ibyte_position = i;
	}
}

int get_oneunit(char *buf, int *startcodepos, int *length)
{
	int i, j, k;

	i = next_startcode(p_irabs);

	if (i != 0) {
		if (i == -1)
			io_printf(
					"\narrive at stream end and start code is not found!");
		if (i == -2)
			io_printf("\np->ibyte_position error!");

	}
	startcode_offset =
			p_irabs->ibyte_position
					- 3 + (bitstream_buf_used-1)
					* SVA_STREAM_BUF_SIZE;
	buf[0] = 0;
	buf[1] = 0;
	buf[2] = 1;
	*startcodepos = 3;
	i = read_n_bit(p_irabs, 8, &j);
	buf[3] = (char)j;

	check_type(buf[3]);
	if (buf[3] == SEQUENCE_END_CODE) {
		*length = 4;
		return -1;
	}
	k = 4;
	while (1) {
		i = read_n_bit(p_irabs, 8, &j);
		if (i < 0)
			break;
		buf[k++] = (char)j;
		if (k >= (MAX_CODED_FRAME_SIZE - 1))
			break;
	}
	if (p_irabs->iclear_bitsnum > 0) {
		int shift;

		shift = 8 - p_irabs->iclear_bitsnum;
		i = read_n_bit(p_irabs, p_irabs->iclear_bitsnum, &j);

		if (j != 0)
			buf[k++] = (char)(j << shift);
		stat_bits_ptr->last_unit_bits += shift;
	}
	*length = k;
	return k;
}

/*unsigned char tmp_buf[MAX_CODED_FRAME_SIZE] __attribute__ ((aligned(64)));*/
/*unsigned char tmp_buf[MAX_CODED_FRAME_SIZE] __aligned(64);*/
int header(void)
{
	unsigned char *buf;
	int startcodepos, length;

	unsigned char *tmp_buf;

	tmp_buf = (unsigned char *)avsp_heap_adr;

	buf = &tmp_buf[0];
	while (1) {
		start_codeposition = get_oneunit(buf, &startcodepos, &length);

		switch (buf[startcodepos]) {
		case SEQUENCE_HEADER_CODE:
			io_printf(
					"# SEQUENCE_HEADER_CODE (0x%02x) found at offset %d (0x%x)\n",
					buf[startcodepos], startcode_offset,
					startcode_offset);
			break;
		case EXTENSION_START_CODE:
			io_printf(
					"# EXTENSION_START_CODE (0x%02x) found at offset %d (0x%x)\n",
					buf[startcodepos], startcode_offset,
					startcode_offset);
			break;
		case USER_DATA_START_CODE:
			io_printf(
					"# USER_DATA_START_CODE (0x%02x) found at offset %d (0x%x)\n",
					buf[startcodepos], startcode_offset,
					startcode_offset);
			break;
		case VIDEO_EDIT_CODE:
			io_printf(
					"# VIDEO_EDIT_CODE (0x%02x) found at offset %d (0x%x)\n",
					buf[startcodepos], startcode_offset,
					startcode_offset);
			break;
		case I_PICTURE_START_CODE:
			io_printf(
					"# I_PICTURE_START_CODE (0x%02x) found at offset %d (0x%x)\n",
					buf[startcodepos], startcode_offset,
					startcode_offset);
			break;
		case PB_PICTURE_START_CODE:
			io_printf(
					"# PB_PICTURE_START_CODE (0x%02x) found at offset %d (0x%x)\n",
					buf[startcodepos], startcode_offset,
					startcode_offset);
			break;
		case SEQUENCE_END_CODE:
			io_printf(
					"# SEQUENCE_END_CODE (0x%02x) found at offset %d (0x%x)\n",
					buf[startcodepos], startcode_offset,
					startcode_offset);
			break;
		default:
			io_printf(
					"# SLICE_START_CODE (0x%02x) found at offset %d (0x%x)\n",
					buf[startcodepos], startcode_offset,
					startcode_offset);
#if 0
			io_printf("VLD_MEM_VIFIFO_START_PTR %x\r\n",
					READ_VREG(VLD_MEM_VIFIFO_START_PTR));
			io_printf("VLD_MEM_VIFIFO_CURR_PTR %x\r\n",
					READ_VREG(VLD_MEM_VIFIFO_CURR_PTR));
			io_printf("VLD_MEM_VIFIFO_END_PTR %x\r\n",
					READ_VREG(VLD_MEM_VIFIFO_END_PTR));
			io_printf("VLD_MEM_VIFIFO_WP %x\r\n"
					READ_VREG(VLD_MEM_VIFIFO_WP));
			io_printf("VLD_MEM_VIFIFO_RP %x\r\n",
					READ_VREG(VLD_MEM_VIFIFO_RP));
			io_printf("VLD_MEM_VBUF_RD_PTR %x\r\n"
					READ_VREG(VLD_MEM_VBUF_RD_PTR));
			io_printf("VLD_MEM_VIFIFO_BUF_CNTL %x\r\n",
					READ_VREG(VLD_MEM_VIFIFO_BUF_CNTL));
			io_printf("PARSER_VIDEO_HOLE %x\r\n",
					READ_MPEG_REG(PARSER_VIDEO_HOLE));
#endif
			if ((buf[startcodepos] >= SLICE_START_CODE_MIN
				&& buf[startcodepos]
				<= SLICE_START_CODE_MAX)
				&& ((!img->seq_header_indicate)
				|| (img->type == B_IMG
				&& img->b_discard_flag
				== 1
				&& !img->no_forward_reference))) {
				break;
			} else if (buf[startcodepos] >= SLICE_START_CODE_MIN) {

				first_slice_length = length;
				first_slice_startpos = startcodepos;

				temp_slice_buf = &tmp_buf[0];
				return SOP;
			} else {
				io_printf("Can't find start code");
				return -EOS;
			}
		}
	}

}

/*
 *************************************************************************
 * Function:Allocates a Bitstream
 * Input:
 * Output:allocated Bitstream point
 * Return:
 * Attention:
 *************************************************************************
 */
struct bitstream_s *alloc_bitstream(void)
{
	struct bitstream_s *bitstream;

	bitstream = (struct bitstream_s *)local_alloc(1,
		sizeof(struct bitstream_s));
	if (bitstream == NULL) {
		io_printf(
			"AllocBitstream: Memory allocation for Bitstream failed");
		return NULL;
	}
	bitstream->stream_buffer = (unsigned char *)local_alloc(
			MAX_CODED_FRAME_SIZE,
			sizeof(unsigned char));
	if (bitstream->stream_buffer == NULL) {
		io_printf(
				"AllocBitstream: Memory allocation for streamBuffer failed");
		return NULL;
	}

	return bitstream;
}

void biari_init_context_logac(struct bi_context_type_s *ctx)
{
	ctx->LG_PMPS = (QUARTER << LG_PMPS_SHIFTNO) - 1;
	ctx->MPS = 0;
	ctx->cycno = 0;
}

#define BIARI_CTX_INIT1_LOG(jj, ctx)\
{\
	for (j = 0; j < jj; j++)\
		biari_init_context_logac(&(ctx[j]));\
}

#define BIARI_CTX_INIT2_LOG(ii, jj, ctx)\
{\
	for (i = 0; i < ii; i++)\
		for (j = 0; j < jj; j++)\
			biari_init_context_logac(&(ctx[i][j]));\
}

#define BIARI_CTX_INIT3_LOG(ii, jj, kk, ctx)\
{\
	for (i = 0; i < ii; i++)\
		for (j = 0; j < jj; j++)\
			for (k = 0; k < kk; k++)\
				biari_init_context_logac(&(ctx[i][j][k]));\
}

#define BIARI_CTX_INIT4_LOG(ii, jj, kk, ll, ctx)\
{\
	for (i = 0; i < ii; i++)\
		for (j = 0; j < jj; j++)\
			for (k = 0; k < kk; k++)\
				for (l = 0; l < ll; l++)\
					biari_init_context_logac\
					(&(ctx[i][j][k][l]));\
}

void init_contexts(struct img_par *img)
{
	struct motion_info_contexts_s *mc = img->current_slice->mot_ctx;
	struct texture_info_contexts *tc = img->current_slice->tex_ctx;
	int i, j;

#ifdef DUMP_DEBUG
	if (avs_get_debug_flag() & SLICE_INFO_DUMP)
		io_printf(" ---- init_contexts ----\n");
#endif

	BIARI_CTX_INIT2_LOG(3, NUM_MB_TYPE_CTX, mc->mb_type_contexts);
	BIARI_CTX_INIT2_LOG(2, NUM_B8_TYPE_CTX, mc->b8_type_contexts);
	BIARI_CTX_INIT2_LOG(2, NUM_MV_RES_CTX, mc->mv_res_contexts);
	BIARI_CTX_INIT2_LOG(2, NUM_REF_NO_CTX, mc->ref_no_contexts);
	BIARI_CTX_INIT1_LOG(NUM_DELTA_QP_CTX, mc->delta_qp_contexts);
	BIARI_CTX_INIT1_LOG(NUM_MB_AFF_CTX, mc->mb_aff_contexts);

	BIARI_CTX_INIT1_LOG(NUM_IPR_CTX, tc->ipr_contexts);
	BIARI_CTX_INIT1_LOG(NUM_CIPR_CTX, tc->cipr_contexts);
	BIARI_CTX_INIT2_LOG(3, NUM_CBP_CTX, tc->cbp_contexts);
	BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_BCBP_CTX, tc->bcbp_contexts);
	BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_ONE_CTX, tc->one_contexts);
	BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_ABS_CTX, tc->abs_contexts);
	BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_MAP_CTX, tc->fld_map_contexts);
	BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_LAST_CTX,
			tc->fld_last_contexts);
	BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_MAP_CTX, tc->map_contexts);
	BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_LAST_CTX, tc->last_contexts);
#ifdef TEST_WEIGHTING_AEC
	biari_init_context_logac(&mc->mb_weighting_pred);
#endif
}

/*!
 ************************************************************************
 * \brief
 *    Allocation of contexts models for the motion info
 *    used for arithmetic decoding
 *
 ************************************************************************
 */
struct motion_info_contexts_s *create_contexts_motioninfo(void)
{
	struct motion_info_contexts_s *deco_ctx;

	deco_ctx = (struct motion_info_contexts_s *)local_alloc(1,
			sizeof(struct motion_info_contexts_s));
	if (deco_ctx == NULL)
		no_mem_exit("create_contexts_motioninfo: deco_ctx");

	return deco_ctx;
}

/*!
 ************************************************************************
 * \brief
 *    Allocates of contexts models for the texture info
 *    used for arithmetic decoding
 ************************************************************************
 */
struct texture_info_contexts *create_contexts_textureinfo(void)
{
	struct texture_info_contexts *deco_ctx;

	deco_ctx = (struct texture_info_contexts *)local_alloc(1,
			sizeof(struct texture_info_contexts));
	if (deco_ctx == NULL)
		no_mem_exit("create_contexts_textureinfo: deco_ctx");

	return deco_ctx;
}

struct datapartition *alloc_partition(int n)
{
	struct datapartition *part_arr, *datapart;
	int i;

	part_arr =
	(struct datapartition *)local_alloc(n, sizeof(struct datapartition));
	if (part_arr == NULL) {
		no_mem_exit(
				"alloc_partition: Memory allocation for Data Partition failed");
		return NULL;
	}

#if LIWR_FIX
	part_arr[0].bitstream = NULL;
#else
	for (i = 0; i < n; i++) {
		datapart = &(part_arr[i]);
		datapart->bitstream = (struct bitstream_s *)local_alloc(1,
				sizeof(struct bitstream_s));
		if (datapart->bitstream == NULL) {
			no_mem_exit(
					"alloc_partition: Memory allocation for Bitstream failed");
			return NULL;
		}
	}
#endif
	return part_arr;
}

int malloc_slice(struct img_par *img)
{
	struct slice_s *currslice;

	img->current_slice =
	(struct slice_s *)local_alloc(1, sizeof(struct slice_s));
	currslice = img->current_slice;
	if (currslice == NULL) {
		no_mem_exit(
			"Memory allocation for struct slice_s datastruct Failed"
			);
		return 0;
	}
	if (1) {

		currslice->mot_ctx = create_contexts_motioninfo();
		if (currslice->mot_ctx == NULL)
			return 0;

		currslice->tex_ctx = create_contexts_textureinfo();
		if (currslice->tex_ctx == NULL)
			return 0;
	}
#if LIWR_FIX
	currslice->max_part_nr = 1;
#else
	currslice->max_part_nr = 3;
#endif
	currslice->part_arr = alloc_partition(currslice->max_part_nr);
	if (currslice->part_arr == NULL)
		return 0;
	return 1;
}

void init(struct img_par *img)
{
	int i;

	for (i = 0; i < 256; i++)
		img->quad[i] = i * i;
}

/*
 *************************************************************************
 * Function:Allocate 2D memory array -> int array2D[rows][columns]
 * Input:
 * Output: memory size in bytes
 * Return:
 * Attention:
 *************************************************************************
 */

int get_mem2Dint(int ***array2D, int rows, int columns)
{
	int i;

	*array2D = (int **)local_alloc(rows, sizeof(int *));
	if (*array2D == NULL) {
		no_mem_exit("get_mem2Dint: array2D");
		return -1;
	}
	(*array2D)[0] = (int *)local_alloc(rows * columns, sizeof(int));
	if ((*array2D)[0] == NULL) {
		no_mem_exit("get_mem2Dint: array2D");
		return -1;
	}

	for (i = 1; i < rows; i++)
		(*array2D)[i] = (*array2D)[i - 1] + columns;

	return rows * columns * sizeof(int);
}

int initial_decode(void)
{
	int i, j;
	int ret;
	int img_height = (vertical_size + img->auto_crop_bottom);
	int memory_size = 0;

	ret = malloc_slice(img);
	if (ret == 0)
		return 0;

	mb_data = (struct macroblock *)local_alloc(
			(img->width / MB_BLOCK_SIZE)
			* (img_height /*vertical_size*/
			/ MB_BLOCK_SIZE), sizeof(struct macroblock));
	if (mb_data == NULL) {
		no_mem_exit("init_global_buffers: mb_data");
		return 0;
	}

	if (progressive_sequence) {
		int size;
		size = get_mem2Dint(&(img->ipredmode),
				img->width / B8_SIZE * 2 + 4,
				vertical_size / B8_SIZE * 2 + 4);
		if (size == -1)
			return 0;

		memory_size += size;
	} else {
		int size;
		size = get_mem2Dint(&(img->ipredmode),
				img->width / B8_SIZE * 2 + 4,
				(vertical_size + 32) / (2 * B8_SIZE) * 4 + 4);
		if (size == -1)
			return 0;

		memory_size += size;
	}

	for (i = 0; i < img->width / (B8_SIZE) * 2 + 4; i++) {
		for (j = 0; j < img->height / (B8_SIZE) * 2 + 4; j++)
			img->ipredmode[i][j] = -1;
	}

	init(img);
	img->number = 0;
	img->type = I_IMG;
	img->imgtr_last_p = 0;
	img->imgtr_next_p = 0;

	img->new_seq_header_flag = 1;
	img->new_sequence_flag = 1;

	return 1;
}

void aec_new_slice(void)
{
	last_dquant = 0;
}

/*!
 ************************************************************************
 * \brief
 *    Initializes the DecodingEnvironment for the arithmetic coder
 ************************************************************************
 */

void arideco_start_decoding(struct decoding_environment_s *dep,
	unsigned char *cpixcode,
		int firstbyte, int *cpixcode_len, int slice_type)
{

	dcodestrm = cpixcode;
	dcodestrm_len = cpixcode_len;
	*dcodestrm_len = firstbyte;

	s1 = 0;
	t1 = QUARTER - 1;
	value_s = 0;

	value_t = 0;

	{
		int i;

		dbits_to_go = 0;
		for (i = 0; i < B_BITS - 1; i++) {
			if (--dbits_to_go < 0)
				get_byte();

			value_t = (value_t << 1)
					| ((dbuffer >> dbits_to_go) & 0x01);
		}
	}

	while (value_t < QUARTER) {
		if (--dbits_to_go < 0)
			get_byte();

		value_t = (value_t << 1) | ((dbuffer >> dbits_to_go) & 0x01);
		value_s++;
	}
	value_t = value_t & 0xff;

	dec_final = dec_bypass = 0;



}

/*
 *************************************************************************
 * Function:Checks the availability of neighboring macroblocks of
 the current macroblock for prediction and context determination;
 marks the unavailable MBs for intra prediction in the
 ipredmode-array by -1. Only neighboring MBs in the causal
 past of the current MB are checked.
 * Input:
 * Output:
 * Return:
 * Attention:
 *************************************************************************
 */

void checkavailabilityofneighbors(struct img_par *img)
{
	int i, j;
	const int mb_width = img->width / MB_BLOCK_SIZE;
	const int mb_nr = img->current_mb_nr;
	struct macroblock *curr_mb = &mb_data[mb_nr];
	int check_value;
	int remove_prediction;

	curr_mb->mb_available_up = NULL;
	curr_mb->mb_available_left = NULL;

	for (i = 0; i < 3; i++)
		for (j = 0; j < 3; j++)
			mb_data[mb_nr].mb_available[i][j] = NULL;

	mb_data[mb_nr].mb_available[1][1] = curr_mb;

	if (img->pix_x >= MB_BLOCK_SIZE) {
		remove_prediction = curr_mb->slice_nr
				!= mb_data[mb_nr - 1].slice_nr;

		if (remove_prediction)

		{

			img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y
					+ 1) * 2] = -1;
			img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y
					+ 1) * 2 + 1] = -1;
			img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y
					+ 2) * 2] = -1;
			img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y
					+ 2) * 2 + 1] = -1;
		}
		if (!remove_prediction)
			curr_mb->mb_available[1][0] = &(mb_data[mb_nr - 1]);

	}

	check_value = (img->pix_y >= MB_BLOCK_SIZE);
	if (check_value) {
		remove_prediction = curr_mb->slice_nr
				!= mb_data[mb_nr - mb_width].slice_nr;

		if (remove_prediction) {
			img->ipredmode
			[(img->block_x + 1) * 2][(img->block_y + 1)
					* 2 - 1] = -1;
			img->ipredmode[(img->block_x + 1) * 2 + 1][(img->block_y
					+ 1) * 2 - 1] = -1;
			img->ipredmode[(img->block_x + 1) * 2 + 2][(img->block_y
					+ 1) * 2 - 1] = -1;
			img->ipredmode[(img->block_x + 1) * 2 + 3][(img->block_y
					+ 1) * 2 - 1] = -1;
		}

		if (!remove_prediction) {
			curr_mb->mb_available[0][1] =
					&(mb_data[mb_nr - mb_width]);
		}
	}

	if (img->pix_y >= MB_BLOCK_SIZE && img->pix_x >= MB_BLOCK_SIZE) {
		remove_prediction = curr_mb->slice_nr
				!= mb_data[mb_nr - mb_width - 1].slice_nr;

		if (remove_prediction) {
			img->ipredmode[img->block_x * 2 + 1][img->block_y * 2
					+ 1] = -1;
		}
		if (!remove_prediction) {
			curr_mb->mb_available[0][0] = &(mb_data[mb_nr - mb_width
					- 1]);
		}
	}

	if (img->pix_y >= MB_BLOCK_SIZE
			&& img->pix_x < (img->width - MB_BLOCK_SIZE)) {
		if (curr_mb->slice_nr == mb_data[mb_nr - mb_width + 1].slice_nr)
			curr_mb->mb_available[0][2] = &(mb_data[mb_nr - mb_width
					+ 1]);
	}

	if (1) {
		curr_mb->mbaddr_a = mb_nr - 1;
		curr_mb->mbaddr_b = mb_nr - img->pic_width_inmbs;
		curr_mb->mbaddr_c = mb_nr - img->pic_width_inmbs + 1;
		curr_mb->mbaddr_d = mb_nr - img->pic_width_inmbs - 1;

		curr_mb->mbavail_a =
		(curr_mb->mb_available[1][0] != NULL) ? 1 : 0;
		curr_mb->mbavail_b =
		(curr_mb->mb_available[0][1] != NULL) ? 1 : 0;
		curr_mb->mbavail_c =
		(curr_mb->mb_available[0][2] != NULL) ? 1 : 0;
		curr_mb->mbavail_d =
		(curr_mb->mb_available[0][0] != NULL) ? 1 : 0;

	}

}

void checkavailabilityofneighborsaec(void)
{

	int i, j;
	const int mb_width = img->width / MB_BLOCK_SIZE;
	const int mb_nr = img->current_mb_nr;
	struct macroblock *curr_mb = &(mb_data[mb_nr]);
	int check_value;

	for (i = 0; i < 3; i++)
		for (j = 0; j < 3; j++)
			mb_data[mb_nr].mb_available[i][j] = NULL;
	mb_data[mb_nr].mb_available[1][1] = &(mb_data[mb_nr]);

	if (img->pix_x >= MB_BLOCK_SIZE) {
		int remove_prediction = curr_mb->slice_nr
				!= mb_data[mb_nr - 1].slice_nr;
		if (!remove_prediction)
			curr_mb->mb_available[1][0] = &(mb_data[mb_nr - 1]);
	}

	check_value = (img->pix_y >= MB_BLOCK_SIZE);
	if (check_value) {
		int remove_prediction = curr_mb->slice_nr
				!= mb_data[mb_nr - mb_width].slice_nr;

		if (!remove_prediction) {
			curr_mb->mb_available[0][1] =
					&(mb_data[mb_nr - mb_width]);
		}
	}

	if (img->pix_y >= MB_BLOCK_SIZE && img->pix_x >= MB_BLOCK_SIZE) {
		int remove_prediction = curr_mb->slice_nr
				!= mb_data[mb_nr - mb_width - 1].slice_nr;
		if (!remove_prediction) {
			curr_mb->mb_available[0][0] = &(mb_data[mb_nr - mb_width
					- 1]);
		}
	}

	if (img->pix_y >= MB_BLOCK_SIZE
			&& img->pix_x < (img->width - MB_BLOCK_SIZE)) {
		if (curr_mb->slice_nr == mb_data[mb_nr - mb_width + 1].slice_nr)
			curr_mb->mb_available[0][2] = &(mb_data[mb_nr - mb_width
					+ 1]);
	}
	curr_mb->mb_available_left = curr_mb->mb_available[1][0];
	curr_mb->mb_available_up = curr_mb->mb_available[0][1];
	curr_mb->mbaddr_a = mb_nr - 1;
	curr_mb->mbaddr_b = mb_nr - img->pic_width_inmbs;
	curr_mb->mbaddr_c = mb_nr - img->pic_width_inmbs + 1;
	curr_mb->mbaddr_d = mb_nr - img->pic_width_inmbs - 1;

	curr_mb->mbavail_a = (curr_mb->mb_available[1][0] != NULL) ? 1 : 0;
	curr_mb->mbavail_b = (curr_mb->mb_available[0][1] != NULL) ? 1 : 0;
	curr_mb->mbavail_c = (curr_mb->mb_available[0][2] != NULL) ? 1 : 0;
	curr_mb->mbavail_d = (curr_mb->mb_available[0][0] != NULL) ? 1 : 0;
}

/*
 *************************************************************************
 * Function:initializes the current macroblock
 * Input:
 * Output:
 * Return:
 * Attention:
 *************************************************************************
 */

void start_macroblock(struct img_par *img)
{
	int i, j, k, l;
	struct macroblock *curr_mb;

#ifdef AVSP_LONG_CABAC
#else

#endif

	curr_mb = &mb_data[img->current_mb_nr];

	/* Update coordinates of the current macroblock */
	img->mb_x = (img->current_mb_nr) % (img->width / MB_BLOCK_SIZE);
	img->mb_y = (img->current_mb_nr) / (img->width / MB_BLOCK_SIZE);

#ifdef DUMP_DEBUG
	if (avs_get_debug_flag() & MB_NUM_DUMP)
		io_printf(" #Begin MB : %d, (%x, %x) es_ptr %d\n",
			img->current_mb_nr, img->mb_x, img->mb_y, es_ptr);
#endif


	total_mb_count = total_mb_count + 1;

	/* Define vertical positions */
	img->block_y = img->mb_y * BLOCK_SIZE / 2; /* luma block position */
	img->block8_y = img->mb_y * BLOCK_SIZE / 2;
	img->pix_y = img->mb_y * MB_BLOCK_SIZE; /* luma macroblock position */
	if (chroma_format == 2)
		img->pix_c_y = img->mb_y *
		MB_BLOCK_SIZE; /* chroma macroblock position */
	else
		img->pix_c_y = img->mb_y *
		MB_BLOCK_SIZE / 2; /* chroma macroblock position */

	/* Define horizontal positions */
	img->block_x = img->mb_x * BLOCK_SIZE / 2; /* luma block position */
	img->block8_x = img->mb_x * BLOCK_SIZE / 2;
	img->pix_x = img->mb_x * MB_BLOCK_SIZE; /* luma pixel position */
	img->pix_c_x = img->mb_x *
	MB_BLOCK_SIZE / 2; /* chroma pixel position */

	checkavailabilityofneighbors(img);

	/*<!*******EDIT START BY lzhang ******************/

	if (1)
		checkavailabilityofneighborsaec();
	/*<!*******EDIT end BY lzhang ******************/

	curr_mb->qp = img->qp;
	curr_mb->mb_type = 0;
	curr_mb->delta_quant = 0;
	curr_mb->cbp = 0;
	curr_mb->cbp_blk = 0;
	curr_mb->c_ipred_mode = DC_PRED_8;
	curr_mb->c_ipred_mode_2 = DC_PRED_8;

	for (l = 0; l < 2; l++)
		for (j = 0; j < BLOCK_MULTIPLE; j++)
			for (i = 0; i < BLOCK_MULTIPLE; i++)
				for (k = 0; k < 2; k++)
					curr_mb->mvd[l][j][i][k] = 0;

	curr_mb->cbp_bits = 0;

	for (j = 0; j < MB_BLOCK_SIZE; j++)
		for (i = 0; i < MB_BLOCK_SIZE; i++)
			img->m7[i][j] = 0;

	for (j = 0; j < 2 * BLOCK_SIZE; j++)
		for (i = 0; i < 2 * BLOCK_SIZE; i++) {
			img->m8[0][i][j] = 0;
			img->m8[1][i][j] = 0;
			img->m8[2][i][j] = 0;
			img->m8[3][i][j] = 0;
		}

	curr_mb->lf_disable = 1;

	img->weighting_prediction = 0;
}

/*
 *************************************************************************
 * Function:init macroblock I and P frames
 * Input:
 * Output:
 * Return:
 * Attention:
 *************************************************************************
 */

void init_macroblock(struct img_par *img)
{
	int i, j;


	for (i = 0; i < 4; i++) {
		for (j = 0; j < 4; j++) {
			img->ipredmode[img->block_x * 2 + i + 2][img->block_y
					* 2 + j + 2] = -1;
		}
	}

}

/*
 *************************************************************************
 * Function:Interpret the mb mode for I-Frames
 * Input:
 * Output:
 * Return:
 * Attention:
 *************************************************************************
 */

void interpret_mb_mode_i(struct img_par *img)
{
	int i;

	struct macroblock *curr_mb = &mb_data[img->current_mb_nr];
	int num = 4;

	curr_mb->mb_type = I8MB;


	current_mb_intra = 1;

	for (i = 0; i < 4; i++) {
		curr_mb->b8mode[i] = IBLOCK;
		curr_mb->b8pdir[i] = -1;
	}

	for (i = num; i < 4; i++) {
		curr_mb->b8mode[i] =
				curr_mb->mb_type_2 == P8x8 ?
						4 : curr_mb->mb_type_2;
		curr_mb->b8pdir[i] = 0;
	}
}

const int pred_4x4[9][9] = {{0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 1, 1, 1, 1, 1, 1,
		1, 1}, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {0, 0, 0, 3, 3, 3, 3, 3, 3},
		{0, 1, 4, 4, 4, 4, 4, 4, 4}, {0, 1, 5, 5, 5, 5, 5, 5, 5}, {0, 0,
				0, 0, 0, 0, 6, 0, 0},
		{0, 1, 7, 7, 7, 7, 7, 7, 7}, {0, 0, 0, 0, 4, 5, 6, 7, 8}

};

const int pred_4x4to8x8[9] = {0, 1, 2, 3, 4, 1, 0, 1, 0

};

const int pred_8x8to4x4[5] = {0, 1, 2, 3, 4};

void read_ipred_block_modes(struct img_par *img, int b8)
{
	int bi, bj, dec;
	struct syntaxelement curr_se;
	struct macroblock *curr_mb;
	int j2;
	int mostprobableintrapredmode;
	int upintrapredmode;
	int uprightintrapredmode;
	int leftintrapredmode;
	int leftdownintrapredmode;
	int intrachromapredmodeflag;

	struct slice_s *currslice = img->current_slice;
	struct datapartition *dp;

	curr_mb = mb_data + img->current_mb_nr;
	intrachromapredmodeflag = IS_INTRA(curr_mb);

	curr_se.type = SE_INTRAPREDMODE;
#if TRACE
	strncpy(curr_se.tracestring, "Ipred Mode", TRACESTRING_SIZE);
#endif

	if (b8 < 4) {
		if (curr_mb->b8mode[b8] == IBLOCK) {
			intrachromapredmodeflag = 1;

			if (1) {
				dp = &(currslice->part_arr[0]);
				curr_se.reading = read_intrapredmode_aec;
				dp->read_syntax_element(&curr_se, img, dp);

				if (curr_se.value1 == -1)
					push_es(1, 1);
				else
					push_es(curr_se.value1, 3);


			}
			bi = img->block_x + (b8 & 1);
			bj = img->block_y + (b8 / 2);

			upintrapredmode = img->ipredmode[(bi + 1) * 2][(bj) * 2
					+ 1];
			uprightintrapredmode =
					img->ipredmode[(bi + 1) * 2 + 1][(bj)
							* 2 + 1];
			leftintrapredmode =
					img->ipredmode[(bi) * 2 + 1][(bj + 1)
							* 2];
			leftdownintrapredmode = img->ipredmode[(bi) * 2 + 1][(bj
					+ 1) * 2 + 1];

			if ((upintrapredmode < 0) || (leftintrapredmode < 0)) {
				mostprobableintrapredmode = DC_PRED;
			} else if ((upintrapredmode < NO_INTRA_PMODE)
					&& (leftintrapredmode <
						NO_INTRA_PMODE)) {
				mostprobableintrapredmode =
					upintrapredmode
					< leftintrapredmode ?
					upintrapredmode :
					leftintrapredmode;
			} else if (upintrapredmode < NO_INTRA_PMODE) {
				mostprobableintrapredmode = upintrapredmode;
			} else if (leftintrapredmode < NO_INTRA_PMODE) {
				mostprobableintrapredmode = leftintrapredmode;
			} else {
				mostprobableintrapredmode =
					pred_4x4[leftintrapredmode
					- INTRA_PMODE_4x4][upintrapredmode
					- INTRA_PMODE_4x4];
				mostprobableintrapredmode =
				pred_4x4to8x8[mostprobableintrapredmode];
			}



			dec =
					(curr_se.value1 == -1) ?
					mostprobableintrapredmode :
					curr_se.value1
					+ (curr_se.value1
					>= mostprobableintrapredmode);

#ifdef DUMP_DEBUG
			if (avs_get_debug_flag() & MB_INFO_DUMP)
				io_printf(" - ipredmode[%d] : %d\n", b8, dec);
#endif

			img->ipredmode[(1 + bi) * 2][(1 + bj) * 2] = dec;
			img->ipredmode[(1 + bi) * 2 + 1][(1 + bj) * 2] = dec;
			img->ipredmode[(1 + bi) * 2][(1 + bj) * 2 + 1] = dec;
			img->ipredmode[(1 + bi) * 2 + 1][(1 + bj) * 2 + 1] =
					dec;

			j2 = bj;
		}
	} else if (b8 == 4 && curr_mb->b8mode[b8 - 3] == IBLOCK) {

		curr_se.type = SE_INTRAPREDMODE;
#if TRACE
		strncpy(curr_se.tracestring,
			"Chroma intra pred mode", TRACESTRING_SIZE);
#endif

		if (1) {
			dp = &(currslice->part_arr[0]);
			curr_se.reading = read_cipredmode_aec;
			dp->read_syntax_element(&curr_se, img, dp);
		} else

		{
		}
		curr_mb->c_ipred_mode = curr_se.value1;

		push_es(UE[curr_se.value1][0], UE[curr_se.value1][1]);

#ifdef DUMP_DEBUG
		if (avs_get_debug_flag() & MB_INFO_DUMP)
			io_printf(" * UE c_ipred_mode read : %d\n",
				curr_mb->c_ipred_mode);
#endif

		if (curr_se.value1 < DC_PRED_8 || curr_se.value1 > PLANE_8) {
#ifdef DUMP_DEBUG
			if (avs_get_debug_flag() & MB_INFO_DUMP)
				io_printf("%d\n", img->current_mb_nr);
#endif
			pr_info("illegal chroma intra pred mode!\n");
		}
	}
}

/*!
 ************************************************************************
 * \brief
 *    This function is used to arithmetically decode the coded
 *    block pattern of a given MB.
 ************************************************************************
 */
void readcp_aec(struct syntaxelement *se, struct img_par *img,
		struct decoding_environment_s *dep_dp)
{
	struct texture_info_contexts *ctx = img->current_slice->tex_ctx;
	struct macroblock *curr_mb = &mb_data[img->current_mb_nr];

	int mb_x, mb_y;
	int a, b;
	int curr_cbp_ctx, curr_cbp_idx;
	int cbp = 0;
	int cbp_bit;
	int mask;

	for (mb_y = 0; mb_y < 4; mb_y += 2) {
		for (mb_x = 0; mb_x < 4; mb_x += 2) {
			if (curr_mb->b8mode[mb_y + (mb_x / 2)] == IBLOCK)
				curr_cbp_idx = 0;
			else
				curr_cbp_idx = 1;

			if (mb_y == 0) {
				if (curr_mb->mb_available_up == NULL)
					b = 0;
				else {
					b = ((((curr_mb->mb_available_up)->cbp
							& (1 << (2 + mb_x / 2)))
							== 0) ? 1 : 0);
				}

			} else
				b = (((cbp & (1 << (mb_x / 2))) == 0) ? 1 : 0);

			if (mb_x == 0) {
				if (curr_mb->mb_available_left == NULL)
					a = 0;
				else {
					a =
					((((curr_mb->mb_available_left)->cbp
					& (1
					<< (2
					* (mb_y
					/ 2)
					+ 1)))
					== 0) ?
					1 : 0);
				}
			} else
				a = (((cbp & (1 << mb_y)) == 0) ? 1 : 0);
			curr_cbp_ctx = a + 2 * b;
			mask = (1 << (mb_y + mb_x / 2));
			cbp_bit = biari_decode_symbol(dep_dp,
					ctx->cbp_contexts[0] + curr_cbp_ctx);

			if (cbp_bit)
				cbp += mask;
		}
	}
	curr_cbp_ctx = 0;
	cbp_bit = biari_decode_symbol(dep_dp,
			ctx->cbp_contexts[1] + curr_cbp_ctx);

	if (cbp_bit) {
		curr_cbp_ctx = 1;
		cbp_bit = biari_decode_symbol(dep_dp,
				ctx->cbp_contexts[1] + curr_cbp_ctx);
		if (cbp_bit) {
			cbp += 48;

		} else {
			curr_cbp_ctx = 1;
			cbp_bit = biari_decode_symbol(dep_dp,
					ctx->cbp_contexts[1] + curr_cbp_ctx);
			cbp += (cbp_bit == 1) ? 32 : 16;

		}
	}

	se->value1 = cbp;
	if (!cbp)
		last_dquant = 0;



}

/*!
 ************************************************************************
 * \brief
 *    This function is used to arithmetically decode the delta qp
 *     of a given MB.
 ************************************************************************
 */
void readdquant_aec(struct syntaxelement *se, struct img_par *img,
		struct decoding_environment_s *dep_dp)
{
	struct motion_info_contexts_s *ctx = img->current_slice->mot_ctx;

	int act_ctx;
	int act_sym;
	int dquant;


	act_ctx = ((last_dquant != 0) ? 1 : 0);

	act_sym = 1
			- biari_decode_symbol(dep_dp,
					ctx->delta_qp_contexts + act_ctx);
	if (act_sym != 0) {
		act_ctx = 2;
		act_sym = unary_bin_decode(dep_dp,
				ctx->delta_qp_contexts + act_ctx, 1);
		act_sym++;
	}
	act_sym &= 0x3f;
	push_es(UE[act_sym][0], UE[act_sym][1]);

	dquant = (act_sym + 1) / 2;
	if ((act_sym & 0x01) == 0)
		dquant = -dquant;
	se->value1 = dquant;

	last_dquant = dquant;

}

int csyntax;

#define CHECKDELTAQP {\
	if (img->qp+curr_mb->delta_quant > 63\
			|| img->qp+curr_mb->delta_quant < 0) {\
		csyntax = 0;\
		transcoding_error_flag = 1;\
		io_printf("error(0) (%3d|%3d) @ MB%d\n",\
			curr_mb->delta_quant,\
			img->qp+curr_mb->delta_quant,\
			img->picture_structure == 0 \
			? img->current_mb_nr_fld : img->current_mb_nr);\
		} }

int dct_level[65];
int dct_run[65];
int pair_pos;
int dct_pairs = -1;
const int t_chr[5] = {0, 1, 2, 4, 3000};

void readrunlevel_aec_ref(struct syntaxelement *se, struct img_par *img,
		struct decoding_environment_s *dep_dp)
{
	int pairs, rank, pos;
	int run, level, abslevel, symbol;
	int sign;

	if (dct_pairs < 0) {
		struct bi_context_type_s (*primary)[NUM_MAP_CTX];
		struct bi_context_type_s *pctx;
		struct bi_context_type_s *pCTX2;
		int ctx, ctx2, offset;

		if (se->context == LUMA_8x8) {
			if (img->picture_structure == 0) {
				primary =
				img->current_slice->tex_ctx->fld_map_contexts;
			} else {
				primary =
				img->current_slice->tex_ctx->map_contexts;
			}
		} else {
			if (img->picture_structure == 0) {
				primary =
				img->current_slice->tex_ctx->fld_last_contexts;
			} else {
				primary =
				img->current_slice->tex_ctx->last_contexts;
			}
		}

		rank = 0;
		pos = 0;
		for (pairs = 0; pairs < 65; pairs++) {
#ifdef DECODING_SANITY_CHECK
			/*max index is NUM_BLOCK_TYPES - 1*/
			pctx = primary[rank & 0x7];
#else
			pctx = primary[rank];
#endif
			if (rank > 0) {
#ifdef DECODING_SANITY_CHECK
				/*max index is NUM_BLOCK_TYPES - 1*/
				pCTX2 = primary[(5 + (pos >> 5)) & 0x7];
#else
				pCTX2 = primary[5 + (pos >> 5)];
#endif
				ctx2 = (pos >> 1) & 0x0f;
				ctx = 0;


				if (biari_decode_symbolw(dep_dp, pctx + ctx,
						pCTX2 + ctx2)) {
					break;
				}
			}

			ctx = 1;
			symbol = 0;
			while (biari_decode_symbol(dep_dp, pctx + ctx) == 0) {
				symbol += 1;
				ctx++;
				if (ctx >= 2)
					ctx = 2;
			}
			abslevel = symbol + 1;

			if (biari_decode_symbol_eq_prob(dep_dp)) {
				level = -abslevel;
				sign = 1;
			} else {
				level = abslevel;
				sign = 0;
			}
#if TRACE
			tracebits2("level", 1, level);
#endif

			if (abslevel == 1)
				offset = 4;
			else
				offset = 6;
			symbol = 0;
			ctx = 0;
			while (biari_decode_symbol(dep_dp, pctx + ctx + offset)
					== 0) {
				symbol += 1;
				ctx++;
				if (ctx >= 1)
					ctx = 1;
			}
			run = symbol;

#if TRACE
			tracebits2("run", 1, run);
#endif
			dct_level[pairs] = level;
			dct_run[pairs] = run;
			if (abslevel > t_chr[rank]) {
				if (abslevel <= 2)
					rank = abslevel;
				else if (abslevel <= 4)
					rank = 3;
				else
					rank = 4;
			}
			pos += (run + 1);
			if (pos >= 64)
				pos = 63;
		}
		dct_pairs = pairs;
		pair_pos = dct_pairs;
	}

	if (dct_pairs > 0) {
		se->value1 = dct_level[pair_pos - 1];
		se->value2 = dct_run[pair_pos - 1];
		pair_pos--;
	} else {

		se->value1 = se->value2 = 0;
	}

	if ((dct_pairs--) == 0)
		pair_pos = 0;
}

int b8_ctr;
#if 0
int curr_residual_chroma[4][16][16];
int curr_residual_luma[16][16];
#endif

const int SCAN[2][64][2] = {{{0, 0}, {0, 1}, {0, 2}, {1, 0}, {0, 3}, {0, 4}, {1,
		1}, {1, 2}, {0, 5}, {0, 6}, {1, 3}, {2, 0}, {2, 1}, {0, 7}, {1,
		4}, {2, 2}, {3, 0}, {1, 5}, {1, 6}, {2, 3}, {3, 1}, {3, 2}, {4,
		0}, {1, 7}, {2, 4}, {4, 1}, {2, 5}, {3, 3}, {4, 2}, {2, 6}, {3,
		4}, {4, 3}, {5, 0}, {5, 1}, {2, 7}, {3, 5}, {4, 4}, {5, 2}, {6,
		0}, {5, 3}, {3, 6}, {4, 5}, {6, 1}, {6, 2}, {5, 4}, {3, 7}, {4,
		6}, {6, 3}, {5, 5}, {4, 7}, {6, 4}, {5, 6}, {6, 5}, {5, 7}, {6,
		6}, {7, 0}, {6, 7}, {7, 1}, {7, 2}, {7, 3}, {7, 4}, {7, 5}, {7,
		6}, {7, 7} }, {{0, 0}, {1, 0}, {0, 1}, {0, 2}, {1, 1}, {2, 0}, {
		3, 0}, {2, 1}, {1, 2}, {0, 3}, {0, 4}, {1, 3}, {2, 2}, {3, 1}, {
		4, 0}, {5, 0}, {4, 1}, {3, 2}, {2, 3}, {1, 4}, {0, 5}, {0, 6}, {
		1, 5}, {2, 4}, {3, 3}, {4, 2}, {5, 1}, {6, 0}, {7, 0}, {6, 1}, {
		5, 2}, {4, 3}, {3, 4}, {2, 5}, {1, 6}, {0, 7}, {1, 7}, {2, 6}, {
		3, 5}, {4, 4}, {5, 3}, {6, 2}, {7, 1}, {7, 2}, {6, 3}, {5, 4}, {
		4, 5}, {3, 6}, {2, 7}, {3, 7}, {4, 6}, {5, 5}, {6, 4}, {7, 3}, {
		7, 4}, {6, 5}, {5, 6}, {4, 7}, {5, 7}, {6, 6}, {7, 5}, {7, 6}, {
		6, 7}, {7, 7} } };

const int SCAN_4x4[16][2] = {{0, 0}, {1, 0}, {0, 1}, {0, 2}, {1, 1}, {2, 0}, {3,
		0}, {2, 1}, {1, 2}, {0, 3}, {1, 3}, {2, 2}, {3, 1}, {3, 2}, {2,
		3}, {3, 3} };

/*
 *************************************************************************
 * Function:
 * Input:
 * Output:
 * Return:
 * Attention:
 *************************************************************************
 */

void encode_golomb_word(unsigned int symbol, unsigned int grad0,
		unsigned int max_levels, unsigned int *res_bits,
		unsigned int *res_len)
{
	unsigned int level, res, numbits;

	res = 1UL << grad0;
	level = 1UL;
	numbits = 1UL + grad0;

	while (symbol >= res && level < max_levels) {
		symbol -= res;
		res = res << 1;
		level++;
		numbits += 2UL;
	}

	if (level >= max_levels) {
		if (symbol >= res)
			symbol = res - 1UL;
	}

	*res_bits = res | symbol;
	*res_len = numbits;
}

/*
 *************************************************************************
 * Function:
 * Input:
 * Output:
 * Return:
 * Attention:
 *************************************************************************
 */

void encode_multilayer_golomb_word(unsigned int symbol,
		const unsigned int *grad, const unsigned int *max_levels,
		unsigned int *res_bits, unsigned int *res_len)
{
	unsigned int accbits, acclen, bits, len, tmp;

	accbits = acclen = 0UL;

	while (1) {
		encode_golomb_word(symbol, *grad, *max_levels, &bits, &len);
		accbits = (accbits << len) | bits;
		acclen += len;
#ifdef AVSP_LONG_CABAC
#else
		assert(acclen <= 32UL);
#endif
		tmp = *max_levels - 1UL;

		if (!((len == (tmp << 1) + (*grad))
				&& (bits == (1UL << (tmp + *grad)) - 1UL)))
			break;

		tmp = *max_levels;
		symbol -= (((1UL << tmp) - 1UL) << (*grad)) - 1UL;
		grad++;
		max_levels++;
	}
	*res_bits = accbits;
	*res_len = acclen;
}

/*
 *************************************************************************
 * Function:
 * Input:
 * Output:
 * Return:
 * Attention:
 *************************************************************************
 */

int writesyntaxelement_golomb(struct syntaxelement *se, int write_to_stream)
{
	unsigned int bits, len, i;
	unsigned int grad[4], max_lev[4];

	if (!(se->golomb_maxlevels & ~0xFF))
		encode_golomb_word(se->value1, se->golomb_grad,
				se->golomb_maxlevels, &bits, &len);
	else {
		for (i = 0UL; i < 4UL; i++) {
			grad[i] = (se->golomb_grad >> (i << 3)) & 0xFFUL;
			max_lev[i] = (se->golomb_maxlevels >> (i << 3))
					& 0xFFUL;
		}
		encode_multilayer_golomb_word(se->value1, grad, max_lev, &bits,
				&len);
	}

	se->len = len;
	se->bitpattern = bits;

	if (write_to_stream)
		push_es(bits, len);
	return se->len;
}

/*
 *************************************************************************
 * Function:Get coded block pattern and coefficients (run/level)
 from the bitstream
 * Input:
 * Output:
 * Return:
 * Attention:
 *************************************************************************
 */

void read_cbpandcoeffsfrom_nal(struct img_par *img)
{

	int tablenum;
	int inumblk;
	int inumcoeff;
	int symbol2D;
	int escape_level_diff;
	const int (*AVS_2DVLC_table_intra)[26][27];
	const int (*AVS_2DVLC_table_chroma)[26][27];
	int write_to_stream;
	struct syntaxelement currse_enc;
	struct syntaxelement *e_currse = &currse_enc;

	int coeff_save[65][2];
	int coeff_ptr;

	int ii, jj;
	int mb_nr = img->current_mb_nr;

	int m2, jg2;
	struct macroblock *curr_mb = &mb_data[mb_nr];

	int block8x8;

	int block_x, block_y;

	struct slice_s *currslice = img->current_slice;
	int level, run, coef_ctr, len, k, i0, j0, uv, qp;

	int boff_x, boff_y, start_scan;
	struct syntaxelement curr_se;
	struct datapartition *dp;

	AVS_2DVLC_table_intra = AVS_2DVLC_INTRA;
	AVS_2DVLC_table_chroma = AVS_2DVLC_CHROMA;
	write_to_stream = 1;

	dct_pairs = -1;

	curr_mb->qp = img->qp;
	qp = curr_mb->qp;


	for (block_y = 0; block_y < 4; block_y += 2) {/* all modes */
	for (block_x = 0; block_x < 4; block_x += 2) {
		block8x8 = 2 * (block_y / 2) + block_x / 2;
		if (curr_mb->cbp & (1 << block8x8)) {
			tablenum = 0;
			inumblk = 1;
			inumcoeff = 65;
			coeff_save[0][0] = 0;
			coeff_save[0][1] = 0;
			coeff_ptr = 1;

			b8_ctr = block8x8;

			boff_x = (block8x8 % 2) << 3;
			boff_y = (block8x8 / 2) << 3;

			img->subblock_x = boff_x >> 2;
			img->subblock_y = boff_y >> 2;

			start_scan = 0;
			coef_ctr = start_scan - 1;
			level = 1;
			img->is_v_block = 0;
			img->is_intra_block = IS_INTRA(curr_mb);
			for (k = start_scan;
				(k < 65) && (level != 0);
				k++) {

				curr_se.context = LUMA_8x8;
				curr_se.type =
				(IS_INTRA(curr_mb)) ?
					SE_LUM_AC_INTRA :
					SE_LUM_AC_INTER;

				dp = &(currslice->part_arr[0]);
				curr_se.reading =
					readrunlevel_aec_ref;
				dp->
				read_syntax_element(&curr_se,
					img, dp);
				level = curr_se.value1;
				run = curr_se.value2;
				len = curr_se.len;

				if (level != 0) {
					coeff_save[coeff_ptr][0] =
					run;
					coeff_save[coeff_ptr][1] =
					level;
					coeff_ptr++;
				}



				if (level != 0) {/* leave if len = 1 */
					coef_ctr += run + 1;
					if ((img->picture_structure
						== FRAME)) {
						ii =
						SCAN[img->picture_structure]
						[coef_ctr][0];
						jj =
						SCAN[img->picture_structure]
						[coef_ctr][1];
					} else {
						ii =
						SCAN[img->picture_structure]
						[coef_ctr][0];
						jj =
						SCAN[img->picture_structure]
						[coef_ctr][1];
					}

				}
			}

			while (coeff_ptr > 0) {
				run =
						coeff_save[coeff_ptr
								- 1][0];
				level =
						coeff_save[coeff_ptr
								- 1][1];

				coeff_ptr--;

				symbol2D = CODE2D_ESCAPE_SYMBOL;
				if (level > -27 && level < 27
					&& run < 26) {
					if (tablenum == 0)

						symbol2D =
						AVS_2DVLC_table_intra
						[tablenum]
						[run][abs(
						level)
						- 1];
					else

						symbol2D =
						AVS_2DVLC_table_intra
						[tablenum]
						[run][abs(
					level)];
					if (symbol2D >= 0
							&& level
									< 0)
						symbol2D++;
					if (symbol2D < 0)

						symbol2D =
						(CODE2D_ESCAPE_SYMBOL
						+ (run
						<< 1)
						+ ((level
						> 0) ?
						1 :
						0));
				}

				else {

					symbol2D =
						(CODE2D_ESCAPE_SYMBOL
						+ (run
						<< 1)
						+ ((level
						> 0) ?
						1 :
						0));
				}



				e_currse->type = SE_LUM_AC_INTER;
				e_currse->value1 = symbol2D;
				e_currse->value2 = 0;

				e_currse->golomb_grad =
						vlc_golomb_order
						[0][tablenum][0];
				e_currse->golomb_maxlevels =
						vlc_golomb_order
						[0][tablenum][1];

				writesyntaxelement_golomb(
						e_currse,
						write_to_stream);

				if (symbol2D
						>= CODE2D_ESCAPE_SYMBOL) {

					e_currse->type =
							SE_LUM_AC_INTER;
					e_currse->golomb_grad =
							1;
					e_currse->golomb_maxlevels =
							11;
					escape_level_diff =
						abs(
						level)
						- ((run
						> MaxRun[0][tablenum]) ?
						1 :
						refabslevel[tablenum][run]);
					e_currse->value1 =
							escape_level_diff;

					writesyntaxelement_golomb(
							e_currse,
							write_to_stream);

				}

				if (abs(level)
					> incvlc_intra[tablenum]) {
					if (abs(level) <= 2)
						tablenum =
						abs(
						level);
					else if (abs(level) <= 4)
						tablenum = 3;
					else if (abs(level) <= 7)
						tablenum = 4;
					else if (abs(level)
							<= 10)
						tablenum = 5;
					else
						tablenum = 6;
				}
			}


		}
		}
	}



	m2 = img->mb_x * 2;
	jg2 = img->mb_y * 2;


	uv = -1;
	block_y = 4;
#if 0
	qp = QP_SCALE_CR[curr_mb->qp];
#endif
	for (block_x = 0; block_x < 4; block_x += 2) {

		uv++;


		b8_ctr = (uv + 4);
		if ((curr_mb->cbp >> (uv + 4)) & 0x1) {

			tablenum = 0;
			inumblk = 1;
			inumcoeff = 65;
			coeff_save[0][0] = 0;
			coeff_save[0][1] = 0;
			coeff_ptr = 1;

			coef_ctr = -1;
			level = 1;
			img->subblock_x = 0;
			img->subblock_y = 0;
			curr_se.context = CHROMA_AC;
			curr_se.type = (IS_INTRA(curr_mb) ?
					SE_CHR_AC_INTRA :
					SE_CHR_AC_INTER);
			dp = &(currslice->part_arr[0]);
			curr_se.reading = readrunlevel_aec_ref;
			img->is_v_block = uv;
			img->is_intra_block = IS_INTRA(curr_mb);
			for (k = 0; (k < 65) && (level != 0); k++) {

				dp->read_syntax_element
				(&curr_se, img, dp);
				level = curr_se.value1;
				run = curr_se.value2;
				len = curr_se.len;

				if (level != 0) {
					coeff_save[coeff_ptr][0] = run;
					coeff_save[coeff_ptr][1] =
							level;
					coeff_ptr++;
				}


				if (level != 0) {
					coef_ctr = coef_ctr + run + 1;
					if ((img->picture_structure
						== FRAME)
						/*&& (!curr_mb->mb_field)*/) {
						i0 =
						SCAN[img->picture_structure]
						[coef_ctr][0];
						j0 =
						SCAN[img->picture_structure]
						[coef_ctr][1];
					} else {
						i0 =
						SCAN[img->picture_structure]
						[coef_ctr][0];
						j0 =
						SCAN[img->picture_structure]
						[coef_ctr][1];
					}

				}
			}

			while (coeff_ptr > 0) {

				run = coeff_save[coeff_ptr - 1][0];
				level = coeff_save[coeff_ptr - 1][1];

				coeff_ptr--;

				symbol2D = CODE2D_ESCAPE_SYMBOL;
				if (level > -27 && level < 27
						&& run < 26) {
					if (tablenum == 0)

						symbol2D =
						AVS_2DVLC_table_chroma
						[tablenum][run][abs(
						level)
						- 1];
					else
						symbol2D =
							AVS_2DVLC_table_chroma
							[tablenum][run][abs(
							level)];
					if (symbol2D >= 0
						&& level < 0)
						symbol2D++;
					if (symbol2D < 0)
						symbol2D =
						(CODE2D_ESCAPE_SYMBOL
						+ (run
						<< 1)
						+ ((level
						> 0) ?
						1 :
						0));
				}

				else {
					symbol2D =
					(CODE2D_ESCAPE_SYMBOL
					+ (run
					<< 1)
					+ ((level
					> 0) ?
					1 :
					0));
				}

				e_currse->type = SE_LUM_AC_INTER;
				e_currse->value1 = symbol2D;
				e_currse->value2 = 0;
				e_currse->golomb_grad =
						vlc_golomb_order[2]
						[tablenum][0];
				e_currse->golomb_maxlevels =
						vlc_golomb_order[2]
						[tablenum][1];

				writesyntaxelement_golomb(e_currse,
						write_to_stream);

				/*
				 * if (write_to_stream)
				 * {
				 * bitCount[BITS_COEFF_UV_MB]+=e_currse->len;
				 * e_currse++;
				 * curr_mb->currSEnr++;
				 * }
				 * no_bits+=e_currse->len;


				 * if (icoef == 0) break;
				 */

				if (symbol2D >= CODE2D_ESCAPE_SYMBOL) {

					e_currse->type = SE_LUM_AC_INTER;
					e_currse->golomb_grad = 0;
					e_currse->golomb_maxlevels = 11;
					escape_level_diff =
						abs(level)
						- ((run
						> MaxRun[2][tablenum]) ?
						1 :
						refabslevel[tablenum
						+ 14][run]);
					e_currse->value1 =
							escape_level_diff;

					writesyntaxelement_golomb(
							e_currse,
							write_to_stream);

				}

				if (abs(level)
				> incvlc_chroma[tablenum]) {
					if (abs(level) <= 2)
						tablenum = abs(level);
					else if (abs(level) <= 4)
						tablenum = 3;
					else
						tablenum = 4;
				}
			}

		}
	}
}

/*
 *************************************************************************
 * Function:Get the syntax elements from the NAL
 * Input:
 * Output:
 * Return:
 * Attention:
 *************************************************************************
 */

int read_one_macroblock(struct img_par *img)
{
	int i, j;

	struct syntaxelement curr_se;
	struct macroblock *curr_mb = &mb_data[img->current_mb_nr];

	int cabp_flag;

	int tempcbp;
	int fixqp;

	struct slice_s *currslice = img->current_slice;
	struct datapartition *dp;

	fixqp = (fixed_picture_qp || fixed_slice_qp);

	for (i = 0; i < 8; i++)
		for (j = 0; j < 8; j++) {
			img->m8[0][i][j] = 0;
			img->m8[1][i][j] = 0;
			img->m8[2][i][j] = 0;
			img->m8[3][i][j] = 0;
		}

	current_mb_skip = 0;

	curr_mb->qp = img->qp;
	curr_se.type = SE_MBTYPE;
	curr_se.mapping = linfo_ue;

	curr_mb->mb_type_2 = 0;

	if (img->type == I_IMG)
		curr_mb->mb_type = 0;

	interpret_mb_mode_i(img);

	init_macroblock(img);

	if ((IS_INTRA(curr_mb)) && (img->abt_flag)) {

#if TRACE
		strncpy(curr_se.tracestring, "cabp_flag", TRACESTRING_SIZE);
#endif

		curr_se.len = 1;
		curr_se.type = SE_CABP;
		read_syntaxelement_flc(&curr_se);
		cabp_flag = curr_se.value1;
		if (cabp_flag == 0) {
			curr_mb->CABP[0] = 0;
			curr_mb->CABP[1] = 0;
			curr_mb->CABP[2] = 0;
			curr_mb->CABP[3] = 0;
		} else {
			for (i = 0; i < 4; i++) {
				curr_se.len = 1;
				curr_se.type = SE_CABP;
				read_syntaxelement_flc(&curr_se);
				curr_mb->CABP[i] = curr_se.value1;
			}
		}

	} else {
		curr_mb->CABP[0] = 0;
		curr_mb->CABP[1] = 0;
		curr_mb->CABP[2] = 0;
		curr_mb->CABP[3] = 0;

	}

	if (IS_INTRA(curr_mb)) {
		for (i = 0; i < /*5*/(chroma_format + 4); i++)

			read_ipred_block_modes(img, i);
	}

	curr_se.type = SE_CBP_INTRA;
	curr_se.mapping = linfo_cbp_intra;

#if TRACE
	snprintf(curr_se.tracestring, TRACESTRING_SIZE, "CBP");
#endif

	if (img->type == I_IMG || IS_INTER(curr_mb)) {
		curr_se.golomb_maxlevels = 0;

		if (1) {
			dp = &(currslice->part_arr[0]);
			curr_se.reading = readcp_aec;
			dp->read_syntax_element(&curr_se, img, dp);
		}


		curr_mb->cbp = curr_se.value1;
		push_es(UE[NCBP[curr_se.value1][0]][0],
				UE[NCBP[curr_se.value1][0]][1]);

	}

# if 1
	if (curr_mb->cbp != 0)
		tempcbp = 1;
	else
		tempcbp = 0;
#else

	if (chroma_format == 2)	{
#if TRACE
		snprintf(curr_se.tracestring, TRACESTRING_SIZE, "CBP422");
#endif
		curr_se.mapping = /*linfo_se*/linfo_ue;
		curr_se.type = SE_CBP_INTRA;
		readsyntaxelement_uvlc(&curr_se, inp);
		curr_mb->cbp01 = curr_se.value1;
		io_printf(" * UE cbp01 read : 0x%02X\n", curr_mb->cbp01);
	}

	if (chroma_format == 2)	{
		if (curr_mb->cbp != 0 || curr_mb->cbp01 != 0)
			tempcbp = 1;
		else
			tempcbp = 0;

	} else {
		if (curr_mb->cbp != 0)
			tempcbp = 1;
		else
			tempcbp = 0;
	}

#endif

	if (IS_INTRA(curr_mb) && (img->abt_flag) && (curr_mb->cbp & (0xF))) {
		curr_mb->CABT[0] = curr_mb->CABP[0];
		curr_mb->CABT[1] = curr_mb->CABP[1];
		curr_mb->CABT[2] = curr_mb->CABP[2];
		curr_mb->CABT[3] = curr_mb->CABP[3];
	} else {

		curr_mb->CABT[0] = 0;
		curr_mb->CABT[1] = 0;
		curr_mb->CABT[2] = 0;
		curr_mb->CABT[3] = 0;

		if (!fixqp && (tempcbp)) {
			if (IS_INTER(curr_mb))
				curr_se.type = SE_DELTA_QUANT_INTER;
			else
				curr_se.type = SE_DELTA_QUANT_INTRA;

#if TRACE
			snprintf(curr_se.tracestring,
				TRACESTRING_SIZE, "Delta quant ");
#endif

			if (1) {
				dp = &(currslice->part_arr[0]);
				curr_se.reading = readdquant_aec;
				dp->read_syntax_element(&curr_se, img, dp);
			}

			curr_mb->delta_quant = curr_se.value1;
#ifdef DUMP_DEBUG
			if (avs_get_debug_flag() & MB_INFO_DUMP) {
				io_printf(" * SE delta_quant read : %d\n",
					curr_mb->delta_quant);
			}
#endif
			CHECKDELTAQP

			if (transcoding_error_flag)
				return -1;

			img->qp = (img->qp - MIN_QP + curr_mb->delta_quant
					+ (MAX_QP - MIN_QP + 1))
					% (MAX_QP - MIN_QP + 1) + MIN_QP;
		}

		if (fixqp) {
			curr_mb->delta_quant = 0;
			img->qp = (img->qp - MIN_QP + curr_mb->delta_quant
					+ (MAX_QP - MIN_QP + 1))
					% (MAX_QP - MIN_QP + 1) + MIN_QP;

		}
#ifdef DUMP_DEBUG
		if (avs_get_debug_flag() & MB_INFO_DUMP)
			io_printf(" - img->qp : %d\n", img->qp);
#endif
	}

	read_cbpandcoeffsfrom_nal(img);
	return DECODE_MB;
}

/*!
 ************************************************************************
 * \brief
 *    finding end of a slice in case this is not the end of a frame
 *
 * Unsure whether the "correction" below actually solves an off-by-one
 * problem or whether it introduces one in some cases :-(  Anyway,
 * with this change the bit stream format works with AEC again.
 * StW, 8.7.02
 ************************************************************************
 */
int aec_startcode_follows(struct img_par *img, int eos_bit)
{
	struct slice_s *currslice = img->current_slice;
	struct datapartition *dp;
	unsigned int bit;
	struct decoding_environment_s *dep_dp;

	dp = &(currslice->part_arr[0]);
	dep_dp = &(dp->de_aec);

	if (eos_bit)
		bit = biari_decode_final(dep_dp);
	else
		bit = 0;

	return bit == 1 ? 1 : 0;
}

#ifdef AVSP_LONG_CABAC
int process_long_cabac(void)
#else
void main(void)
#endif
{
	int data32;
	int current_header;
	int i;
	int tmp;
	int ret;

	int byte_startposition;
	int aec_mb_stuffing_bit;
	struct slice_s *currslice;
#ifdef PERFORMANCE_DEBUG
	pr_info("enter %s\r\n", __func__);
#endif
	transcoding_error_flag = 0;
	ret = 0;
	es_buf = es_write_addr_virt;

	if (local_heap_init(MAX_CODED_FRAME_SIZE * 4) < 0) {
		ret = -1;
		goto End;
	}

	img = (struct img_par *)local_alloc(1, sizeof(struct img_par));
	if (img	== NULL) {
		no_mem_exit("main: img");
		ret = -1;
		goto End;
	}
	stat_bits_ptr = (struct stat_bits *)local_alloc(1,
			sizeof(struct stat_bits));
	if (stat_bits_ptr == NULL) {
		no_mem_exit("main: stat_bits");
		ret = -1;
		goto End;
	}

	curr_stream = alloc_bitstream();
	if (curr_stream == NULL) {
		io_printf("alloc bitstream failed\n");
		ret = -1;
		goto End;
	}

	chroma_format = 1;
	demulate_enable = 0;
	img->seq_header_indicate = 1;

#ifdef AVSP_LONG_CABAC
	data32 = READ_VREG(LONG_CABAC_REQ);
	progressive_sequence = (data32 >> 1) & 1;
	fixed_picture_qp = (data32 >> 2) & 1;
	img->picture_structure = (data32 >> 3) & 1;
	img->type = (data32 >> 4) & 3;
	skip_mode_flag = (data32 >> 6) & 1;

	src_start = READ_VREG(LONG_CABAC_SRC_ADDR);
	des_start = READ_VREG(LONG_CABAC_DES_ADDR);

	data32 = READ_VREG(LONG_CABAC_PIC_SIZE);
	horizontal_size = (data32 >> 0) & 0xffff;
	vertical_size = (data32 >> 16) & 0xffff;
	if (horizontal_size * vertical_size > 1920 * 1080) {
		io_printf("pic size check failed: width = %d, height = %d\n",
			horizontal_size, vertical_size);
		ret = -1;
		goto End;
	}

	vld_mem_start_addr = READ_VREG(VLD_MEM_VIFIFO_START_PTR);
	vld_mem_end_addr = READ_VREG(VLD_MEM_VIFIFO_END_PTR);

#else
	progressive_sequence = 0;
	fixed_picture_qp = 0;
	img->picture_structure = 0;
	img->type = I_IMG;
	skip_mode_flag = 1;
	horizontal_size = 1920;
	vertical_size = 1080;

	src_start = 0;
#endif

	if (horizontal_size % 16 != 0)
		img->auto_crop_right = 16 - (horizontal_size % 16);
	else
		img->auto_crop_right = 0;

	if (!progressive_sequence) {
		if (vertical_size % 32 != 0)
			img->auto_crop_bottom = 32 - (vertical_size % 32);
		else
			img->auto_crop_bottom = 0;
	} else {
		if (vertical_size % 16 != 0)
			img->auto_crop_bottom = 16 - (vertical_size % 16);
		else
			img->auto_crop_bottom = 0;
	}

	img->width = (horizontal_size + img->auto_crop_right);
	if (img->picture_structure)
		img->height = (vertical_size + img->auto_crop_bottom);
	else
		img->height = (vertical_size + img->auto_crop_bottom) / 2;
	img->width_cr = (img->width >> 1);

	img->pic_width_inmbs = img->width / MB_BLOCK_SIZE;
	img->pic_height_inmbs = img->height / MB_BLOCK_SIZE;
	img->pic_size_inmbs = img->pic_width_inmbs * img->pic_height_inmbs;

	io_printf(
			"[LONG CABAC] Start Transcoding from 0x%x to 0x%x Size : %d x %d\r\n",
			src_start, des_start, horizontal_size, vertical_size);
#if 0
	io_printf("VLD_MEM_VIFIFO_START_PTR %x\r\n",
			READ_VREG(VLD_MEM_VIFIFO_START_PTR));
	io_printf("VLD_MEM_VIFIFO_CURR_PTR %x\r\n",
			READ_VREG(VLD_MEM_VIFIFO_CURR_PTR));
	io_printf("VLD_MEM_VIFIFO_END_PTR %x\r\n",
			READ_VREG(VLD_MEM_VIFIFO_END_PTR));
	io_printf("VLD_MEM_VIFIFO_WP %x\r\n",
			READ_VREG(VLD_MEM_VIFIFO_WP));
	io_printf("VLD_MEM_VIFIFO_RP %x\r\n",
			READ_VREG(VLD_MEM_VIFIFO_RP));
	io_printf("VLD_MEM_VBUF_RD_PTR %x\r\n",
			READ_VREG(VLD_MEM_VBUF_RD_PTR));
	io_printf("VLD_MEM_VIFIFO_BUF_CNTL %x\r\n",
			READ_VREG(VLD_MEM_VIFIFO_BUF_CNTL));
#endif
	io_printf(
			"[LONG CABAC] progressive_sequence : %d, fixed_picture_qp : %d, skip_mode_flag : %d\r\n",
			progressive_sequence, fixed_picture_qp, skip_mode_flag);
	io_printf("[LONG CABAC] picture_structure : %d, picture_type : %d\r\n",
			img->picture_structure, img->type);

	open_irabs(p_irabs);


	if (initial_decode() == 0) {
		io_printf("initial_decode failed\n");
		ret = -1;
		goto End;
	}

	init_es();

	current_header = header();
	io_printf("[LONG CABAC] header Return : %d\n", current_header);

	tmp = slice_header(temp_slice_buf, first_slice_startpos,
			first_slice_length);

	init_contexts(img);
	aec_new_slice();
	byte_startposition = (curr_stream->frame_bitoffset) / 8;

	currslice = img->current_slice;

	if (1) {
		for (i = 0; i < 1; i++) {
			img->current_slice->part_arr[i].read_syntax_element =
					read_syntaxelement_aec;
			img->current_slice->part_arr[i].bitstream = curr_stream;
		}
		curr_stream = currslice->part_arr[0].bitstream;
	}
	if ((curr_stream->frame_bitoffset) % 8 != 0)
		byte_startposition++;

	arideco_start_decoding(&img->current_slice->part_arr[0].de_aec,
			curr_stream->stream_buffer, (byte_startposition),
			&(curr_stream->read_len), img->type);

	img->current_mb_nr = 0;
	total_mb_count = 0;
	while (img->current_mb_nr < img->pic_size_inmbs)

	{
		start_macroblock(img);
		if (-1 == read_one_macroblock(img)) {
			ret = -1;
			pr_info("macroblock trans failed, exit\n");
			goto End;
		}
		if (img->cod_counter <= 0)
			aec_mb_stuffing_bit = aec_startcode_follows(img, 1);
		img->current_mb_nr++;
	}

	push_es(0xff, 8);
	io_printf(" Total ES_LENGTH : %d\n", es_ptr);

#ifdef AVSP_LONG_CABAC
	push_es(0xff, 64);
	if (es_buf_is_overflow) {
		io_printf("fatal error: es_buf_is_overflow\n");
		ret = -1;
		goto End;
	}

	if (transcoding_error_flag == 0) {
#if 1
		dma_sync_single_for_device(amports_get_dma_device(),
			es_write_addr_phy,
			es_ptr, DMA_TO_DEVICE);

		wmb(); /**/
#endif
	}
#else
	fclose(f_es);
#endif

End:
#ifdef AVSP_LONG_CABAC
	WRITE_VREG(LONG_CABAC_REQ, 0);
#endif
	local_heap_uninit();
#ifdef PERFORMANCE_DEBUG
	pr_info("exit %s\r\n", __func__);
#endif
	return ret;
}
#endif
